0

我正在使用动态 SQL 编写存储过程。

在我的程序中,我说了大约 10 个类似列的表。

例如,如果我考虑Designation&Department表,Designation表有以下列:

Designation, Code, EntryBy, EntryOn, ModifiedBy, ModifiedOn 

Department表有这些列:

Department, Code, EntryBy, EntryOn, ModifiedBy, ModifiedOn

同样,我还有其他八张桌子。

在我的存储过程中,我需要更新数据并将数据插入所有表中。因此,我没有为每个表编写更新和插入语句,而是使用一个存储过程,它接受表名作为参数并检查该行是否已存在于该表中。

如果该行存在,则该记录将被更新,否则该记录将被插入到相应的表中。

    ALTER PROC UpdateMasterItems
    (
        @MasterTypeTmp  varchar(50),
        @NameTmp    varchar(50),
        @CodeTmp    varchar(10))
    AS
    BEGIN   
       DECLARE @CntTmp numeric(2,0)

       EXEC('select count(*)' + @CntTmp + ' from ' + @MasterTypeTmp + ' where ' + @MasterTypeTmp  + ' = ' + @NameTmp)

       IF(@CntTmp > 1)
       BEGIN
          EXEC('UPDATE ' + @MasterTypeTmp + ' SET ' + 'Code = ' + @CodeTmp + ', ModifiedBy = CURRENT_USER, MOdifiedOn = CURRENT_TIMESTAMP WHERE' + @MasterTypeTmp + ' = ' +  @NameTmp)
          RETURN 10
       END      
       ELSE
       BEGIN    
          EXEC('INSERT INTO ' + @MasterTypeTmp + '(' + @MasterTypeTmp + ', Code, EntryBy, EntryOn, ModifiedBy, ModifiedOn )  VALUES (' + @NameTmp + ',' + @CodeTmp + ',' + 'CURRENT_USER, CURRENT_TIMESTAMP, CURRENT_USER, CURRENT_TIMESTAMP )') 
          RETURN 11
       END
END

表名在哪里@MasterTypeTmp(可以是Department/ Designation.....)

执行过程时出现错误:

执行语句:

EXEC UpdateMasterItems 'Designation', 'TestName', 'TestCode'

错误陈述:

列名“TestName”无效。

列名“TestCode”无效。

但是TestName&TestCode不是列名。这些是列的值。请让我知道我的动态查询是否错误或问题出在哪里!

提前致谢

穆尼卡

4

3 回答 3

0

我认为错误消息是因为您使用'(ie;'Designation'是错误的) 包装了列名。应该Designation

但还有其他问题。

  1. 我认为您不能在动态 sql 之外定义变量并在内部分配它们。因为dynamic sql runs in a different session和因此在范围之外定义的变量是未知的。(即;@CntTmp

  2. 即使您正在检查@CntTmp > 1您并没有真正为其分配 count(*) 值(由于原因 1 无论如何都不会工作)

  3. 如果记录数> 99,您@CntTmp将溢出(如果您没有错误数据,则不是真正的问题)

如果您需要按照您描述的方式完成这项工作,您必须声明变量,检查记录的存在,然后更新/插入all within the same dynamic query。你可以不用变量使用if exists (select ....) update ... else insert...

于 2013-03-15T20:09:15.250 回答
0

首先,这部分会给你一个错误:Error converting data type varchar to numeric.

DECLARE @CntTmp numeric(2,0)
EXEC('select count(*)' + @CntTmp + ' from ' + @MasterTypeTmp + ' where ' + @MasterTypeTmp  + ' = ' + @NameTmp)

因为CntTmp是数字,不能直接在该表达式中使用。

如果你改成这样:

EXEC('select count(*)' + cast(@CntTmp as varchar(30)) + ' from ' + @MasterTypeTmp + ' where ' + @MasterTypeTmp  + ' = ' + @NameTmp)

它会给你一个错误,因为你不能在动态 SQL 中直接使用变量。此外,它不会给你输出,因为CntTmp它是空的。

因此,您可以创建另一个变量来存储从转换到的结果numericvarchar然后执行ISNULL函数来为变量赋值(如果它为空)。

其次,您缺少'列值。

这是工作存储过程:

ALTER PROC UPDATEMASTERITEMS   
( @MASTERTYPETMP VARCHAR(50), @NAMETMP VARCHAR(50), @CODETMP VARCHAR(10))    
AS

BEGIN

DECLARE @CNTTMP NUMERIC(2,0)
DECLARE @CNTTMPVAL VARCHAR(30) = ISNULL(CAST(@CNTTMP AS VARCHAR(30)) , '')

EXEC ('SELECT COUNT(*) ' + @CNTTMPVAL + ' FROM ' + @MASTERTYPETMP + ' WHERE ' + @MASTERTYPETMP  + ' = ''' + @NAMETMP + '''')
IF(@CNTTMP > 1)
    BEGIN
     EXEC('UPDATE ' + @MASTERTYPETMP + ' SET ' + 'CODE = ''' + @CODETMP + ''', MODIFIEDBY = CURRENT_USER, MODIFIEDON = CURRENT_TIMESTAMP WHERE' + @MASTERTYPETMP + ' = ''' +  @NAMETMP + '')
     RETURN 10
    END
ELSE
    BEGIN 
    EXEC('INSERT INTO ' + @MASTERTYPETMP + '(' + @MASTERTYPETMP + ', CODE, ENTRYBY, ENTRYON, MODIFIEDBY, MODIFIEDON )  VALUES (''' + @NAMETMP + ''',''' + @CODETMP + ''',' + 'CURRENT_USER, CURRENT_TIMESTAMP, CURRENT_USER, CURRENT_TIMESTAMP )') 
     RETURN 11
    END

END

无论如何,您可以使用它来格式化您的 SQL

于 2013-03-15T20:13:15.467 回答
0

您的字符串连接丢失了一些',数据库将这些值解释为列名:

EXEC('INSERT INTO ' + @MasterTypeTmp + '(' + @MasterTypeTmp + ', Code, EntryBy, EntryOn, ModifiedBy, ModifiedOn )  
VALUES (''' + @NameTmp + ''',''' + @CodeTmp + ''',' + 'CURRENT_USER, CURRENT_TIMESTAMP, CURRENT_USER, CURRENT_TIMESTAMP )') 
于 2013-03-15T20:08:24.697 回答