我正在使用动态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
不是列名。这些是列的值。如果我的动态查询错误或问题出在哪里,请告诉我!
提前致谢
芒卡
答案 0 :(得分:0)
您的字符串连接缺少某些'
,db将这些值解释为列名:
EXEC('INSERT INTO ' + @MasterTypeTmp + '(' + @MasterTypeTmp + ', Code, EntryBy, EntryOn, ModifiedBy, ModifiedOn )
VALUES (''' + @NameTmp + ''',''' + @CodeTmp + ''',' + 'CURRENT_USER, CURRENT_TIMESTAMP, CURRENT_USER, CURRENT_TIMESTAMP )')
答案 1 :(得分:0)
我认为错误消息是因为您使用'
包装了列名称(即; 'Designation'
错误)。应为Designation
但是还有其他问题。
我认为你不能在动态sql中定义变量并将它们分配到里面。因为dynamic sql runs in a different session
因此在范围之外定义的变量是未知的。 (即; @CntTmp
)
即使您正在检查@CntTmp > 1
,您也没有真正为其分配计数(*)值(由于原因1无论如何也无法正常工作)
如果记录计数>您的@CntTmp
将会溢出99(如果你没有坏数据,那真的不是问题)
如果您需要按照描述的方式完成这项工作,您必须声明变量,检查记录的存在,然后更新/插入 all within the same dynamic query
。您可以使用if exists (select ....) update ... else insert...
答案 2 :(得分: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
为空。
因此,您可以创建另一个变量来存储结果,从numeric
转换为varchar
,然后执行ISNULL函数,如果变量为null,则为变量赋值。
其次,您的列值缺少'
。
这是工作存储过程:
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
无论如何,您可以使用this
格式化SQL