我的任务是保持几个表的更新信息,从外部源引入。为此,我一直在网上寻找将表名作为参数传递的方法,并且所有答案都很复杂和/或抛出错误(例如下面的内容:"' Table& #39;错误显示)
CREATE PROCEDURE sp_Insert_Delta
-- Add the parameters for the stored procedure here
@tableName Table READONLY
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Delete rows in MIRROR database where ID exists in the DELTA database
Delete from [S1].[MIRROR].[dbo].@tableName
Where [ID] in (Select [ID] from [S2].[DELTAS].[dbo].@tableName)
-- Insert all deltas
Insert Into [S1].[MIRROR].[dbo].@tableName
Select * from [S2].[DELTAS].[dbo].@tableName
END
GO
当显式命名时,此脚本工作正常,那么如何参数化表名?
谢谢,
内特
答案 0 :(得分:3)
关于如何因SQL注入漏洞而永远不应该这样做的强制序言。
换句话说,您想要验证输入,我举一个例子,如下所示:
CREATE PROCEDURE sp_Insert_Delta
-- Add the parameters for the stored procedure here
@tableName varchar(max) READONLY
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF EXISTS(SELECT 1 FROM sys.tables WHERE [name] = @tableName)
BEGIN
-- Delete rows in MIRROR database where ID exists in the DELTA database
exec("Delete from [S1].[MIRROR].[dbo]."+@tableName"+
" Where [ID] in (Select [ID] from [S2].[DELTAS].[dbo]."+@tableName);
-- Insert all deltas
exec("Insert Into [S1].[MIRROR].[dbo]."+@tableName)
exec("Select * from [S2].[DELTAS].[dbo]."+@tableName)
END
-- ELSE handle error.
END
GO
注意我现在无法访问SQL Server,因此可能会出现错字。
答案 1 :(得分:2)
使用动态SQL
DECLARE @sql as varchar(4000)
SET @sql = 'Delete from [S1].[MIRROR].[dbo].' + @tableName
+ ' Where [ID] in (Select [ID] from [S2].[DELTAS].[dbo].' + @tableName + ')'
EXEC(@sql)
作为一个例子
答案 2 :(得分:2)
简短的回答是你不能参数化表名。
答案越长,可以通过动态SQL 完成您想要的任务。看起来你正在使用SQL Server。有关详细信息,请参阅问题 Dynamic SQL - EXEC(@SQL) versus EXEC SP_EXECUTESQL(@SQL) 。
然而,实际上不应该将任意表名放入查询中是一种代码气味,向我表明您的数据库设计存在架构问题,并且可能与您的E-R模型有关。