0

在 MicroFocus Cobol 中,我正在使用主机变量创建一个存储过程。SQL代码是这样的:

 CREATE PROCEDURE dbo.LLPSY_PK1_BPS_PROC_INDEX  
 AS 
 BEGIN 
     IF EXISTS (SELECT * FROM sysobjects 
                WHERE id = object_id(N'LLPSY_PK1_BPS_INDEX ') 
                  AND OBJECTPROPERTY(id, N'IsTable') = 1) 
        DROP TABLE LLPSY_PK1_BPS_INDEX 

     IF EXISTS (SELECT * FROM sysobjects 
                WHERE id = object_id(N'LLPSY_PK1_BPS_INDEX_1    ') 
                  AND OBJECTPROPERTY(id, N'IsTable') = 1) 
        DROP TABLE LLPSY_PK1_BPS_INDEX_1    

     IF EXISTS (SELECT * FROM sysobjects 
                WHERE id = object_id(N'LLPSY_PK1_BPS_INDEX_2    ') 
                  AND OBJECTPROPERTY(id, N'IsTable') = 1) 
        DROP TABLE LLPSY_PK1_BPS_INDEX_2    

     SELECT 
         PAYMENT_REF = CASE C.ACNT_TYPE WHEN 1 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 0 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 2 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 4 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))END ,A.ACCNT_CODE AS ACCOUNT,BANKNO=CASE WHEN E.BANK_ACNT_NUM IS NULL THEN''ELSE E.BANK_ACNT_NUM END,AMOUNT=CASE WHEN A.AMOUNT>0 THEN A.AMOUNT ELSE A.AMOUNT*-1 END,A.D_C AS AMOUNT_DC,OTHER_AMOUNT=CASE WHEN A.OTHER_AMT>0 THEN A.OTHER_AMT ELSE A.OTHER_AMT*-1 END,A.D_C AS OTHER_AMOUNT_DC,CAST(A.ACCNT_CODE AS NCHAR(15))+CAST(A.PERIOD AS NCHAR(07))+CONVERT(CHAR(16),A.TRANS_DATETIME,112)AS LEDGER_KEY,CAST(A.JRNAL_NO AS NUMERIC(09))AS JN,CAST(A.JRNAL_LINE AS NUMERIC(09))AS TN,'A'AS BUDGET,' 'AS LOCAL_CURR,' 'AS COUNT,0 AS COUNTS,CAST(' 'AS NCHAR(80))AS TNS,C.DESCR AS ACCOUNT_NAME,A.DESCRIPTN AS DESCRIPTION,A.CONV_CODE,A.TREFERENCE AS TRANS_REF,' 'AS MATCHED,C.ACNT_TYPE AS AT,' 'AS DOUBLES,' 'AS SPLIT,ADD_1=E.A,' 'AS ADD_2,' 'AS ADD_3,PAYMENT_ADD=' ' INTO LLPSY_PK1_BPS_INDEX_1    FROM PK1_A_SALFLDG AS A INNER JOIN PK1_ACNT AS C ON A.ACCNT_CODE=C.ACNT_CODE LEFT JOIN LLPSY_PK1_BNK_BKA_VIEW   AS E ON A.ACCNT_CODE=E.ACCOUNT AND E.A<>'M'  OR  A.ACCNT_CODE=E.ACCOUNT AND E.A= 'M'  AND A.ANAL_T9   =E.BDS       LEFT JOIN PK1_A_SALFLDG_LAD  AS M ON A.ACCNT_CODE=M.ACCNT_CODE AND A.JRNAL_NO=M.JRNAL_NO AND A.JRNAL_LINE=M.JRNAL_LINE WHERE(( A.ACCNT_CODE BETWEEN ? and ? AND C.ACNT_TYPE IN(1)))AND ALLOCATION NOT IN ('A','P','Y','C','R','2','W') UNION SELECT PAYMENT_REF=CASE C.ACNT_TYPE WHEN 1 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 0 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 2 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 4 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))END ,A.ACCNT_CODE AS ACCOUNT,BANKNO=CASE WHEN E.BANK_ACNT_NUM IS NULL THEN''ELSE E.BANK_ACNT_NUM END,AMOUNT=CASE WHEN A.AMOUNT>0 THEN A.AMOUNT ELSE A.AMOUNT*-1 END,A.D_C AS AMOUNT_DC,OTHER_AMOUNT=CASE WHEN A.OTHER_AMT>0 THEN A.OTHER_AMT ELSE A.OTHER_AMT*-1 END,A.D_C AS OTHER_AMOUNT_DC,CAST(A.ACCNT_CODE AS NCHAR(15))+CAST(A.PERIOD AS NCHAR(07))+CONVERT(CHAR(16),A.TRANS_DATETIME,112)AS LEDGER_KEY,CAST(A.JRNAL_NO AS NUMERIC(09))AS JN,CAST(A.JRNAL_LINE AS NUMERIC(09))AS TN,'B'AS BUDGET,' 'AS LOCAL_CURR,' 'AS COUNT,0 AS COUNTS,CAST(' 'AS NCHAR(80))AS TNS,C.DESCR AS ACCOUNT_NAME,A.DESCRIPTN AS DESCRIPTION,A.CONV_CODE,A.TREFERENCE AS TRANS_REF,' 'AS MATCHED,C.ACNT_TYPE AS AT,' 'AS DOUBLES,' 'AS SPLIT,ADD_1=E.A,' 'AS ADD_2,' 'AS ADD_3,PAYMENT_ADD=' '                               FROM PK1_B_SALFLDG AS A INNER JOIN PK1_ACNT AS C ON A.ACCNT_CODE=C.ACNT_CODE LEFT JOIN LLPSY_PK1_BNK_BKA_VIEW   AS E ON A.ACCNT_CODE=E.ACCOUNT AND E.A<>'M'  OR  A.ACCNT_CODE=E.ACCOUNT AND E.A= 'M'  AND A.ANAL_T9   =E.BDS       LEFT JOIN PK1_A_SALFLDG_LAD  AS M ON A.ACCNT_CODE=M.ACCNT_CODE AND A.JRNAL_NO=M.JRNAL_NO AND A.JRNAL_LINE=M.JRNAL_LINE WHERE(( A.ACCNT_CODE BETWEEN ? and ? AND C.ACNT_TYPE IN(1)))AND ALLOCATION NOT IN ('A','P','Y','C','R','2','W')SELECT PAYMENT_REF,ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY=IDENTITY(int,1,1),DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3,PAYMENT_ADD INTO LLPSY_PK1_BPS_INDEX_2     FROM LLPSY_PK1_BPS_INDEX_1   SELECT PAYMENT_REF,ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3 INTO dbo.LLPSY_PK1_BPS_INDEX  FROM LLPSY_PK1_BPS_INDEX_2    WHERE ISNUMERIC(LTRIM(PAYMENT_REF))=1   SET IDENTITY_INSERT LLPSY_PK1_BPS_INDEX  ON  INSERT INTO LLPSY_PK1_BPS_INDEX  (PAYMENT_REF,ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3) SELECT dbo.LLPSY_Remove_AB_String(PAYMENT_REF), ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3 FROM LLPSY_PK1_BPS_INDEX_2    WHERE dbo.LLPSY_Remove_AB_String(PAYMENT_REF)<>'' AND  dbo.LLPSY_Remove_AB_String(PAYMENT_REF)<>PAYMENT_REF
  SET IDENTITY_INSERT LLPSY_PK1_BPS_INDEX  ON  INSERT INTO LLPSY_PK1_BPS_INDEX  (PAYMENT_REF,ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3) SELECT dbo.LLPSY_Remove_AB_String(PAYMENT_ADD)AS PAYMENT_REF, ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3 FROM LLPSY_PK1_BPS_INDEX_2    WHERE PAYMENT_ADD IS NOT NULL AND PAYMENT_ADD<>'' AND dbo.LLPSY_Remove_AB_String(PAYMENT_ADD)<>'' CREATE INDEX PAYMENT_REF_IND ON LLPSY_PK1_BPS_INDEX  (PAYMENT_REF)  CREATE INDEX BANKNO_IND ON LLPSY_PK1_BPS_INDEX  (BANKNO)  CREATE INDEX LEDGER_KEY_IND ON LLPSY_PK1_BPS_INDEX  (LEDGER_KEY)  CREATE INDEX JN_IND ON LLPSY_PK1_BPS_INDEX  (JN)  CREATE INDEX TN_IND ON LLPSY_PK1_BPS_INDEX  (TN)  CREATE NONCLUSTERED INDEX  REC_KEY_IND ON LLPSY_PK1_BPS_INDEX  ([REC_KEY]) 
DROP TABLE LLPSY_PK1_BPS_INDEX_1    
DROP TABLE LLPSY_PK1_BPS_INDEX_2     END

它以这个错误结束:

  1. SQLCODE -156
  2. SQLSTATE 37000
  3. 关键字“PROCEDURE”附近的语法不正确

当我在 SQL Manager 中运行此 SQL 时,它可以正常工作。当我在 SQL Profiler 中跟踪它时,我得到了这个:

declare @p1 int
set @p1=NULL
exec sp_prepare @p1 output,N'@P1 nvarchar(1000),@P2 nvarchar(1000),@P3 nvarchar(1000),@P4 nvarchar(1000)',N'CREATE PROCEDURE dbo.LLPSY_PK1_BPS_PROC_INDEX  AS BEGIN 
 IF EXISTS (select * from sysobjects where id = object_id(N''LLPSY_PK1_BPS_INDEX '') and OBJECTPROPERTY(id, N''IsTable'') = 1) DROP TABLE LLPSY_PK1_BPS_INDEX 
 IF EXISTS (select * from sysobjects where id = object_id(N''LLPSY_PK1_BPS_INDEX_1    '') and OBJECTPROPERTY(id, N''IsTable'') = 1) DROP TABLE LLPSY_PK1_BPS_INDEX_1    
 IF EXISTS (select * from sysobjects where id = object_id(N''LLPSY_PK1_BPS_INDEX_2    '') and OBJECTPROPERTY(id, N''IsTable'') = 1) DROP TABLE LLPSY_PK1_BPS_INDEX_2    
SELECT PAYMENT_REF=CASE C.ACNT_TYPE WHEN 1 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 0 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 2 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 4 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))END ,A.ACCNT_CODE AS ACCOUNT,BANKNO=CASE WHEN E.BANK_ACNT_NUM IS NULL THEN''''ELSE E.BANK_ACNT_NUM END,AMOUNT=CASE WHEN A.AMOUNT>0 THEN A.AMOUNT ELSE A.AMOUNT*-1 END,A.D_C AS AMOUNT_DC,OTHER_AMOUNT=CASE WHEN A.OTHER_AMT>0 THEN A.OTHER_AMT ELSE A.OTHER_AMT*-1 END,A.D_C AS OTHER_AMOUNT_DC,CAST(A.ACCNT_CODE AS NCHAR(15))+CAST(A.PERIOD AS NCHAR(07))+CONVERT(CHAR(16),A.TRANS_DATETIME,112)AS LEDGER_KEY,CAST(A.JRNAL_NO AS NUMERIC(09))AS JN,CAST(A.JRNAL_LINE AS NUMERIC(09))AS TN,''A''AS BUDGET,'' ''AS LOCAL_CURR,'' ''AS COUNT,0 AS COUNTS,CAST('' ''AS NCHAR(80))AS TNS,C.DESCR AS ACCOUNT_NAME,A.DESCRIPTN AS DESCRIPTION,A.CONV_CODE,A.TREFERENCE AS TRANS_REF,'' ''AS MATCHED,C.ACNT_TYPE AS AT,'' ''AS DOUBLES,'' ''AS SPLIT,ADD_1=E.A,'' ''AS ADD_2,'' ''AS ADD_3,PAYMENT_ADD='' '' INTO LLPSY_PK1_BPS_INDEX_1    FROM PK1_A_SALFLDG AS A INNER JOIN PK1_ACNT AS C ON A.ACCNT_CODE=C.ACNT_CODE LEFT JOIN LLPSY_PK1_BNK_BKA_VIEW   AS E ON A.ACCNT_CODE=E.ACCOUNT AND E.A<>''M''  OR  A.ACCNT_CODE=E.ACCOUNT AND E.A= ''M''  AND A.ANAL_T9   =E.BDS       LEFT JOIN PK1_A_SALFLDG_LAD  AS M ON A.ACCNT_CODE=M.ACCNT_CODE AND A.JRNAL_NO=M.JRNAL_NO AND A.JRNAL_LINE=M.JRNAL_LINE WHERE(( A.ACCNT_CODE BETWEEN @P1 and @P2 AND C.ACNT_TYPE IN(1)))AND ALLOCATION NOT IN (''A'',''P'',''Y'',''C'',''R'',''2'',''W'') UNION SELECT PAYMENT_REF=CASE C.ACNT_TYPE WHEN 1 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 0 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 2 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))WHEN 4 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))END ,A.ACCNT_CODE AS ACCOUNT,BANKNO=CASE WHEN E.BANK_ACNT_NUM IS NULL THEN''''ELSE E.BANK_ACNT_NUM END,AMOUNT=CASE WHEN A.AMOUNT>0 THEN A.AMOUNT ELSE A.AMOUNT*-1 END,A.D_C AS AMOUNT_DC,OTHER_AMOUNT=CASE WHEN A.OTHER_AMT>0 THEN A.OTHER_AMT ELSE A.OTHER_AMT*-1 END,A.D_C AS OTHER_AMOUNT_DC,CAST(A.ACCNT_CODE AS NCHAR(15))+CAST(A.PERIOD AS NCHAR(07))+CONVERT(CHAR(16),A.TRANS_DATETIME,112)AS LEDGER_KEY,CAST(A.JRNAL_NO AS NUMERIC(09))AS JN,CAST(A.JRNAL_LINE AS NUMERIC(09))AS TN,''B''AS BUDGET,'' ''AS LOCAL_CURR,'' ''AS COUNT,0 AS COUNTS,CAST('' ''AS NCHAR(80))AS TNS,C.DESCR AS ACCOUNT_NAME,A.DESCRIPTN AS DESCRIPTION,A.CONV_CODE,A.TREFERENCE AS TRANS_REF,'' ''AS MATCHED,C.ACNT_TYPE AS AT,'' ''AS DOUBLES,'' ''AS SPLIT,ADD_1=E.A,'' ''AS ADD_2,'' ''AS ADD_3,PAYMENT_ADD='' ''                               FROM PK1_B_SALFLDG AS A INNER JOIN PK1_ACNT AS C ON A.ACCNT_CODE=C.ACNT_CODE LEFT JOIN LLPSY_PK1_BNK_BKA_VIEW   AS E ON A.ACCNT_CODE=E.ACCOUNT AND E.A<>''M''  OR  A.ACCNT_CODE=E.ACCOUNT AND E.A= ''M''  AND A.ANAL_T9   =E.BDS       LEFT JOIN PK1_A_SALFLDG_LAD  AS M ON A.ACCNT_CODE=M.ACCNT_CODE AND A.JRNAL_NO=M.JRNAL_NO AND A.JRNAL_LINE=M.JRNAL_LINE WHERE(( A.ACCNT_CODE BETWEEN @P3 and @P4 AND C.ACNT_TYPE IN(1)))AND ALLOCATION NOT IN (''A'',''P'',''Y'',''C'',''R'',''2'',''W'')SELECT PAYMENT_REF,ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY=IDENTITY(int,1,1),DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3,PAYMENT_ADD INTO LLPSY_PK1_BPS_INDEX_2     FROM LLPSY_PK1_BPS_INDEX_1   SELECT PAYMENT_REF,ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3 INTO dbo.LLPSY_PK1_BPS_INDEX  FROM LLPSY_PK1_BPS_INDEX_2    WHERE ISNUMERIC(LTRIM(PAYMENT_REF))=1   SET IDENTITY_INSERT LLPSY_PK1_BPS_INDEX  ON  INSERT INTO LLPSY_PK1_BPS_INDEX  (PAYMENT_REF,ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3) SELECT dbo.LLPSY_Remove_AB_String(PAYMENT_REF), ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3 FROM LLPSY_PK1_BPS_INDEX_2    WHERE dbo.LLPSY_Remove_AB_String(PAYMENT_REF)<>'''' AND  dbo.LLPSY_Remove_AB_String(PAYMENT_REF)<>PAYMENT_REF
  SET IDENTITY_INSERT LLPSY_PK1_BPS_INDEX  ON  INSERT INTO LLPSY_PK1_BPS_INDEX  (PAYMENT_REF,ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3) SELECT dbo.LLPSY_Remove_AB_String(PAYMENT_ADD)AS PAYMENT_REF, ACCOUNT,BANKNO,AMOUNT,AMOUNT_DC,OTHER_AMOUNT,OTHER_AMOUNT_DC,LEDGER_KEY,JN,TN,BUDGET,LOCAL_CURR,COUNT,COUNTS,TNS,ACCOUNT_NAME,DESCRIPTION,CONV_CODE,TRANS_REF,MATCHED,AT,REC_KEY,DOUBLES,SPLIT,ADD_1,ADD_2,ADD_3 FROM LLPSY_PK1_BPS_INDEX_2    WHERE PAYMENT_ADD IS NOT NULL AND PAYMENT_ADD<>'''' AND dbo.LLPSY_Remove_AB_String(PAYMENT_ADD)<>'''' CREATE INDEX PAYMENT_REF_IND ON LLPSY_PK1_BPS_INDEX  (PAYMENT_REF)  CREATE INDEX BANKNO_IND ON LLPSY_PK1_BPS_INDEX  (BANKNO)  CREATE INDEX LEDGER_KEY_IND ON LLPSY_PK1_BPS_INDEX  (LEDGER_KEY)  CREATE INDEX JN_IND ON LLPSY_PK1_BPS_INDEX  (JN)  CREATE INDEX TN_IND ON LLPSY_PK1_BPS_INDEX  (TN)  CREATE NONCLUSTERED INDEX  REC_KEY_IND ON LLPSY_PK1_BPS_INDEX  ([REC_KEY]) 
DROP TABLE LLPSY_PK1_BPS_INDEX_1    
DROP TABLE LLPSY_PK1_BPS_INDEX_2     END',1
select @p1

从 SQL Profiler 运行此代码会导致与嵌入式 SQL 相同的错误。请问这里有什么问题吗?

4

1 回答 1

0

不是答案,但作为评论太长了。您有很多过于复杂的代码,这些代码将从相对简单的更改中受益匪浅。你有:

SELECT PAYMENT_REF=CASE C.ACNT_TYPE 
WHEN 1 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int), CAST(30 AS int)) AS NCHAR(30))
WHEN 0 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))
WHEN 2 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30))
WHEN 4 THEN  CAST(SUBSTRING(A.TREFERENCE,CAST(01 AS int),CAST(30 AS int)) AS NCHAR(30)) END ,
  • 您可以简单地将 case 表达式转换为所需的类型。您不需要强制转换每个条件。
  • 对于任何追随您的人,请将您的布尔表达式IN ORDER
  • 数字文字将被隐式转换为适当的数据类型。像 1 和 30 这样的值将被解释为整数。无需投射它们。
  • 在每种情况下,您都使用相同的公式。那么,为什么你要把同样的事情写 4 次来使事情变得过于复杂。
  • substring(1, 30) 与 left(30) 相同。再次,为什么会出现并发症?

所以这个单一的公式可以被浓缩和简化成:

select PAYMENT_REF = cast(case when C.ACNT_TYPE in (0, 1, 2, 4) 
    then left(A.TREFERENCE, 30) else NULL end as NCHAR(30)),

如果需要,您可以省略 ELSE 部分。我更喜欢包含它,因为它向任何阅读作者所做的代码的人表明,事实上,考虑在评估期间没有匹配时会发生什么。简单的格式使代码容易阅读和理解。

最后,数据库中永久表的销毁和创建是一个安全问题和效率问题。最好让合格的 dba 确定此表的位置、组织和索引,然后将其嵌入应用程序逻辑中。您没有考虑对这些表的权限 - 这也具有重要意义。没有聚集索引 AFAIK - 这通常是一个问题。

似乎更好的方法是简单地创建一次存储过程。您使用两个(不是现在令人困惑的四个)参数创建。您的 dba 将创建作为逻辑目标的单个表 - 其他 2 个只是临时存储。粗略、简略和不完整的伪代码:

create procedure dbo.LLPSY_PK1_BPS_PROC_INDEX (@ACCT_START int, @ACCT_END int) as 
begin 
    insert ... 
    select ... 
    where ( A.ACCNT_CODE BETWEEN @ACCT_START and @ACCT_END) ... 
    ...
end;

还有更多的问题需要解决——但你必须从某个地方开始。UNION(不是 UNION ALL)的使用,[select ... into ...] 的多次使用,在特定时间点依赖于应用程序逻辑并特定于应用程序逻辑的过程的构建——所有这些正在制造未来的调试和维护问题。最后一条评论 - 您的代码为大多数语句假定了一个特定的模式,但有一个非常重要的模式(创建过程语句)。要么假设无处不在,要么不假设任何地方。最好不要在没有充分理由的情况下假设。

于 2018-10-19T14:42:30.557 回答