如何在 Netezza 的存储过程中使用 CASE 语法

Posted

技术标签:

【中文标题】如何在 Netezza 的存储过程中使用 CASE 语法【英文标题】:How use CASE syntac in Stored Procedure on Netezza 【发布时间】:2014-11-20 08:48:02 【问题描述】:

我只是 netezza 的新手(运行版本 netezza 版本 7.1.0.1-P1 [Build 37788]),我创建了从另一个数据库加载数据的查询,这是我的查询:

CASE INSTR(B.WIFI.WIFI_DETAIL.LOCATION, ';') WHEN 0 THEN B.WIFI.WIFI_DETAIL.LOCATION ELSE BTRIM(SUBSTR(B.WIFI.WIFI_DETAIL.LOCATION, 1, INSTR(B.WIFI.WIFI_DETAIL.LOCATION, ';')-1)) END AS POI_NAME

它运行完美,但是当我放入存储过程时,它已使用@ScottMcG 的解决方案进行了修改:

create or replace procedure SP_CREATE_TMP_F_WIFIID_AP_UTILISASI()
LANGUAGE NZPLSQL RETURNS INT4 AS
BEGIN_PROC

DECLARE

BEGIN
    /* CREATE TABLE TMP AP UTILISASI WITHOUT CLIENT */
    EXECUTE IMMEDIATE '
        create TABLE TMP_F_AP_UTILISASI as select AVG(ANN.THROUGPUT_V) as AVG_THROUGHPUT
            , SUM(ANN.BYTES_SENT) AS SUM_SENT
            , SUM(ANN.BYTES_RECIEVE) AS SUM_RECIEVE
            , (SUM(ANN.BYTES_RECIEVE)+SUM(ANN.BYTES_SENT)) AS TOTAL_AMOUNT
            , COUNT(ANN.C_MAC_ADDRESS) AS ASSOCIATED_CLIENT_COUNT
            , COUNT(ANN.USER_NAME) AS AUTHENTICATED_CLIENT_COUNT
            , MAX(ANN.TOTAL_WAKTU) AS MAX_SESSION_DURATION
            , ANN.AP_NAME
            , ANN.ASSO_TIME_V
            , ANN.PAKET_NAME
            , ANN.SSID
            , CASE INSTR(AD.LOCATION, ' || quote_literal (';') || ') WHEN 0 THEN AD.LOCATION ELSE BTRIM(SUBSTR(AD.LOCATION, 1, INSTR(AD.LOCATION, ' || quote_literal (';') || ')-1)) END AS POI_NAME
        FROM
            A.USR3.V_ALL_NMS_DETAIL AS ANN
        JOIN A.USR3.V_NMS_AP_DETAIL AS AD
            ON ANN.AP_NAME = AD.AP_NAME
        GROUP BY ANN.AP_NAME
            , ANN.ASSO_TIME_V
            , ANN.PAKET_NAME
            , ANN.SSID
            , AD.LOCATION
    ';

END;

END_PROC;

当我调用该程序时,它仍然无法正常工作:

ERROR: Cross Database Access not supported for this type of command

我从数据库 A 调用,程序在 A 中构建

也许你有解决我问题的想法,,,

或者也许任何人有另一个查询等于这个查询:

CASE INSTR(AD.LOCATION, ' || quote_literal (';') || ') WHEN 0 THEN AD.LOCATION ELSE BTRIM(SUBSTR(AD.LOCATION, 1, INSTR(AD.LOCATION, ' || quote_literal (';') || ')-1)) END AS POI_NAME

谢谢

【问题讨论】:

您必须在 SQL 字符串中转义引号 '。 ';') 应该变成 '';'') 嗨@FrankHeikens,它仍然是错误...错误错误:属性';'没找到 【参考方案1】:

在您的情况下,问题不是 CASE 本身。在存储过程(例如 EXECUTE IMMEDIATE)中使用动态 SQL 时,必须转义嵌入在文本中的引号。您可以通过两种(至少)方式做到这一点。

以下是使用带有字符串文字的 CASE 语句的存储过程的两个示例。第一个使用两个单引号 '' 来表示转义的单引号。第二个使用 quote_literal 函数。

转义引号版本

CREATE OR REPLACE PROCEDURE SP_SAMPLE()
RETURNS INTEGER
EXECUTE AS CALLER
LANGUAGE NZPLSQL AS
BEGIN_PROC

BEGIN

EXECUTE IMMEDIATE 'UPDATE TESTING_TABLE SET COL1 =  CASE INSTR(COL2,'';'') WHEN 0 THEN ''NOT SEMICOLON'' ELSE ''SEMICOLON'' END';

END;
END_PROC;

QUOTE_LITERAL 函数版本

CREATE OR REPLACE PROCEDURE SP_SAMPLE()
RETURNS INTEGER
EXECUTE AS CALLER
LANGUAGE NZPLSQL AS
BEGIN_PROC

BEGIN

EXECUTE IMMEDIATE 'UPDATE TESTING_TABLE SET COL1 =  CASE INSTR(COL2,' || quote_literal (';') ||
    ') WHEN 0 THEN ' || quote_literal('NOT SEMICOLON') || ' ELSE ' || quote_literal('SEMICOLON') || ' END';

END;
END_PROC;

您可以参考文档和示例for running dynamic SQL in Netezza here

【讨论】:

嗨@ScottMcG,我已经尝试过你建议的解决方案,但错误:错误:这种类型的命令不支持跨数据库访问它不能是跨数据库? 当我将表放在一个数据库中时,它仍然出现错误:错误:这种类型的命令不支持跨数据库访问也许你有解决这个问题的另一种解决方案 thx 您运行的是哪个版本的 Netezza?可以用带有quote_literal的全新版本更新您的问题文本吗?另外,存储过程是在哪个数据库中创建的,您从哪个数据库调用它?当您遇到跨数据库访问错误时,向我们展示创建和执行 SP 的完整上下文。【参考方案2】:

试试这个:

    create or replace procedure SP_CREATE_TMP_F_WIFIID_AP_UTILISASI()
LANGUAGE NZPLSQL RETURNS INT4 AS
BEGIN_PROC

DECLARE

BEGIN
    /* CREATE TABLE TMP AP UTILISASI WITHOUT CLIENT */
    EXECUTE IMMEDIATE '
        create TABLE TMP_F_AP_UTILISASI as select AVG(ANN.THROUGPUT_V) as AVG_THROUGHPUT
            , SUM(ANN.BYTES_SENT) AS SUM_SENT
            , SUM(ANN.BYTES_RECIEVE) AS SUM_RECIEVE
            , (SUM(ANN.BYTES_RECIEVE)+SUM(ANN.BYTES_SENT)) AS TOTAL_AMOUNT
            , COUNT(ANN.C_MAC_ADDRESS) AS ASSOCIATED_CLIENT_COUNT
            , COUNT(ANN.USER_NAME) AS AUTHENTICATED_CLIENT_COUNT
            , MAX(ANN.TOTAL_WAKTU) AS MAX_SESSION_DURATION
            , ANN.AP_NAME
            , ANN.ASSO_TIME_V
            , ANN.PAKET_NAME
            , ANN.SSID
            , CASE INSTR(AD.LOCATION, ";") WHEN 0 THEN AD.LOCATION ELSE BTRIM(SUBSTR(AD.LOCATION, 1, INSTR(AD.LOCATION, ";")-1)) END AS POI_NAME
        FROM
            A.USR3.V_ALL_NMS_DETAIL AS ANN
        JOIN A.USR3.V_NMS_AP_DETAIL AS AD
            ON ANN.AP_NAME = AD.AP_NAME
        GROUP BY ANN.AP_NAME
            , ANN.ASSO_TIME_V
            , ANN.PAKET_NAME
            , ANN.SSID
            , AD.LOCATION
    ';

END;

END_PROC;

【讨论】:

感谢您的帮助,但它仍然是错误:(。错误:错误:属性';'未找到

以上是关于如何在 Netezza 的存储过程中使用 CASE 语法的主要内容,如果未能解决你的问题,请参考以下文章

如何访问 Netezza 存储过程中的参数?

如何在 Netezza 中运行代码块

Netezza SQL ALTER TABLE 在存储过程中的替代方案?

我们可以在 Netezza sql 中使用 switch case 吗?

Netezza 存储过程中是不是有任何方法可以将输出放入文件中

从 SAS 调用 Netezza 存储过程