Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Oracle-IF语句插入WHERE子句_C#_Oracle_If Statement - Fatal编程技术网

C# Oracle-IF语句插入WHERE子句

C# Oracle-IF语句插入WHERE子句,c#,oracle,if-statement,C#,Oracle,If Statement,我应该将C代码翻译成Oracle中的存储过程 我在where中编写了一个带有case when的存储过程,但是没有返回正确的数据。我错在哪里 问题在于管理输入参数的IFs 甲骨文: CREATE OR REPLACE PROCEDURE SP_S_RICCFEMESSE ( NUMEROCV IN VARCHAR2, PROFILO IN NUMBER, SALAES IN NUMBER, DATAINIZIO

我应该将C代码翻译成Oracle中的存储过程

我在where中编写了一个带有case when的存储过程,但是没有返回正确的数据。我错在哪里

问题在于管理输入参数的IFs

甲骨文:

CREATE OR REPLACE PROCEDURE SP_S_RICCFEMESSE 
(
    NUMEROCV        IN VARCHAR2,
    PROFILO         IN NUMBER,
    SALAES          IN NUMBER,
    DATAINIZIO      IN VARCHAR2,
    DATAFINE        IN VARCHAR2,
    ric_carteemesse OUT SYS_REFCURSOR
)
AS 
BEGIN
    OPEN ric_carteemesse FOR
       SELECT DISTINCT A.*
                ,DESCARDPRFCFR AS TIPO_CARTA
                ,TO_CHAR(DATNAS,'DD/MM/YYYY') AS DATA_DI_NASCITA 
                ,TO_CHAR(A.DATIVOPSA,'DD/MM/YYYY HH24:MI:SS') AS DATA_EMISSIONE 
                ,TO_CHAR(DATINIVALRTA,'DD/MM/YYYY') AS INIZIO_VALIDITA_CARTA 
                ,TO_CHAR(DATFINIVALRTA,'DD/MM/YYYY') AS FINE_VALIDITA_CARTA 
                ,C.S_DENOMINAZIONE AS SALA_ES 
                ,CASE 
                    WHEN NVL(SCDUP,0) = '0' 
                    THEN 'NO' 
                    WHEN SCDUP > 0 
                    THEN 'SI' 
                END AS DUPLICATO 
FROM 
DEMIRTAFRC A 
INNER JOIN SMART_CARD B 
    ON A.CODSRE = B.COD_SM 
LEFT JOIN RIVENDITA C 
    ON B.S_POSTAZIONE_UM = TO_CHAR(C.COD_RIVENDITA) 
INNER JOIN DANACARDPRFCFR D ON A.CODPRF= D.CARDPRFCFR 
WHERE 
    (B.D_ELETTRIFICAZIONE BETWEEN TO_DATE(DATAINIZIO,'DD/MM/YYYY') AND TO_DATE(DATAFINE,'DD/MM/YYYY') 
    AND A.MDLCSG = 'CBM' AND CODSRE IS NOT NULL)
    AND NUMEROCV = (CASE WHEN NUMEROCV <> '' 
                         THEN A.CODRTA
                         ELSE null 
                    END)
    AND PROFILO = (CASE WHEN PROFILO <> 0 
                        THEN B.COD_REQUISITI
                        ELSE null 
                   END)
    AND SALAES = (CASE WHEN SALAES <> 999
                       THEN B.S_POSTAZIONE_UM
                       ELSE null 
                  END)
ORDER BY A.DATETR DESC;

END SP_S_RICCFEMESSE;

PROFILO、SALES、NUMEROCV列中是否有空值。 如果是,则必须在where part中的该列上设置nvl

因为你说你可能有空,所以试试这个:

 CREATE OR REPLACE PROCEDURE SP_S_RICCFEMESSE 
(
    NUMEROCV        IN VARCHAR2,
    PROFILO         IN NUMBER,
    SALAES          IN NUMBER,
    DATAINIZIO      IN VARCHAR2,
    DATAFINE        IN VARCHAR2,
    ric_carteemesse OUT SYS_REFCURSOR
)


AS 
BEGIN

OPEN ric_carteemesse FOR
SELECT DISTINCT A.*
                ,DESCARDPRFCFR AS TIPO_CARTA
                ,TO_CHAR(DATNAS,'DD/MM/YYYY') AS DATA_DI_NASCITA 
                ,TO_CHAR(A.DATIVOPSA,'DD/MM/YYYY HH24:MI:SS') AS DATA_EMISSIONE 
                ,TO_CHAR(DATINIVALRTA,'DD/MM/YYYY') AS INIZIO_VALIDITA_CARTA 
                ,TO_CHAR(DATFINIVALRTA,'DD/MM/YYYY') AS FINE_VALIDITA_CARTA 
                ,C.S_DENOMINAZIONE AS SALA_ES 
                ,CASE 
                    WHEN NVL(SCDUP,0) = '0' 
                    THEN 'NO' 
                    WHEN SCDUP > 0 
                    THEN 'SI' 
                END AS DUPLICATO 
FROM 
DEMIRTAFRC A 
INNER JOIN SMART_CARD B 
    ON A.CODSRE = B.COD_SM 
LEFT JOIN RIVENDITA C 
    ON B.S_POSTAZIONE_UM = TO_CHAR(C.COD_RIVENDITA) 
INNER JOIN DANACARDPRFCFR D ON A.CODPRF= D.CARDPRFCFR 
WHERE 
    (B.D_ELETTRIFICAZIONE BETWEEN TO_DATE(DATAINIZIO,'DD/MM/YYYY') AND TO_DATE(DATAFINE,'DD/MM/YYYY') 
    AND A.MDLCSG = 'CBM' AND CODSRE IS NOT NULL)
    AND nvl(NUMEROCV, ' ') = (CASE WHEN nvl(NUMEROCV, ' ') <> ' ' 
                         THEN A.CODRTA
                         ELSE null 
                    END)
    AND nvl(PROFILO, 0) = (CASE WHEN nvl(PROFILO, 0) <> 0 
                        THEN B.COD_REQUISITI
                        ELSE null 
                   END)
    AND NVL(SALAES, 0) = (CASE WHEN NVL(SALAES, 0) <> 999
                       THEN B.S_POSTAZIONE_UM
                       ELSE null 
                  END)
ORDER BY A.DATETR DESC;

END SP_S_RICCFEMESSE;

PROFILO、SALES、NUMEROCV列中是否有空值。 如果是,则必须在where part中的该列上设置nvl

因为你说你可能有空,所以试试这个:

 CREATE OR REPLACE PROCEDURE SP_S_RICCFEMESSE 
(
    NUMEROCV        IN VARCHAR2,
    PROFILO         IN NUMBER,
    SALAES          IN NUMBER,
    DATAINIZIO      IN VARCHAR2,
    DATAFINE        IN VARCHAR2,
    ric_carteemesse OUT SYS_REFCURSOR
)


AS 
BEGIN

OPEN ric_carteemesse FOR
SELECT DISTINCT A.*
                ,DESCARDPRFCFR AS TIPO_CARTA
                ,TO_CHAR(DATNAS,'DD/MM/YYYY') AS DATA_DI_NASCITA 
                ,TO_CHAR(A.DATIVOPSA,'DD/MM/YYYY HH24:MI:SS') AS DATA_EMISSIONE 
                ,TO_CHAR(DATINIVALRTA,'DD/MM/YYYY') AS INIZIO_VALIDITA_CARTA 
                ,TO_CHAR(DATFINIVALRTA,'DD/MM/YYYY') AS FINE_VALIDITA_CARTA 
                ,C.S_DENOMINAZIONE AS SALA_ES 
                ,CASE 
                    WHEN NVL(SCDUP,0) = '0' 
                    THEN 'NO' 
                    WHEN SCDUP > 0 
                    THEN 'SI' 
                END AS DUPLICATO 
FROM 
DEMIRTAFRC A 
INNER JOIN SMART_CARD B 
    ON A.CODSRE = B.COD_SM 
LEFT JOIN RIVENDITA C 
    ON B.S_POSTAZIONE_UM = TO_CHAR(C.COD_RIVENDITA) 
INNER JOIN DANACARDPRFCFR D ON A.CODPRF= D.CARDPRFCFR 
WHERE 
    (B.D_ELETTRIFICAZIONE BETWEEN TO_DATE(DATAINIZIO,'DD/MM/YYYY') AND TO_DATE(DATAFINE,'DD/MM/YYYY') 
    AND A.MDLCSG = 'CBM' AND CODSRE IS NOT NULL)
    AND nvl(NUMEROCV, ' ') = (CASE WHEN nvl(NUMEROCV, ' ') <> ' ' 
                         THEN A.CODRTA
                         ELSE null 
                    END)
    AND nvl(PROFILO, 0) = (CASE WHEN nvl(PROFILO, 0) <> 0 
                        THEN B.COD_REQUISITI
                        ELSE null 
                   END)
    AND NVL(SALAES, 0) = (CASE WHEN NVL(SALAES, 0) <> 999
                       THEN B.S_POSTAZIONE_UM
                       ELSE null 
                  END)
ORDER BY A.DATETR DESC;

END SP_S_RICCFEMESSE;

空永远不等于空。因此,如果任何CASE语句转到ELSE分支,则该语句的计算结果将为FALSE。另外,在Oracle中,空字符串与NULL相同是的,这是有争议的,但Oracle已经这样做了将近四十年,这就是它的方式,这意味着这永远是错误的:NUMEROCV

简单的解决方案是,不要在WHERE子句中使用CASE。这一点更加明确:

AND (NUMEROCV is null or NUMEROCV = A.CODRTA)
AND (PROFILO = 0 or PROFILO = B.COD_REQUISITI)
AND (SALAES = 999 or SALAES = B.S_POSTAZIONE_UM))

空永远不等于空。因此,如果任何CASE语句转到ELSE分支,则该语句的计算结果将为FALSE。另外,在Oracle中,空字符串与NULL相同是的,这是有争议的,但Oracle已经这样做了将近四十年,这就是它的方式,这意味着这永远是错误的:NUMEROCV

简单的解决方案是,不要在WHERE子句中使用CASE。这一点更加明确:

AND (NUMEROCV is null or NUMEROCV = A.CODRTA)
AND (PROFILO = 0 or PROFILO = B.COD_REQUISITI)
AND (SALAES = 999 or SALAES = B.S_POSTAZIONE_UM))

如果你有很多标准,你可以动态地构建sql

声明sql\u语句

sql_statement VARCHAR2(...);

sql_statement := 'SELECT .... WHERE ' // your select

IF PROFILO <> 0 THEN // your criteria here
    sql_statement := sql_statement || ' AND B.COD_REQUISITI = ' || PROFILO // your criteria here;

EXECUTE IMMEDIATE(sql_statement);

如果你有很多标准,你可以动态地构建sql

声明sql\u语句

sql_statement VARCHAR2(...);

sql_statement := 'SELECT .... WHERE ' // your select

IF PROFILO <> 0 THEN // your criteria here
    sql_statement := sql_statement || ' AND B.COD_REQUISITI = ' || PROFILO // your criteria here;

EXECUTE IMMEDIATE(sql_statement);