【问题标题】:Passing a Table name as a parameter将表名作为参数传递
【发布时间】:2016-10-07 00:05:09
【问题描述】:

我的任务是使用要从外部来源引入的信息来更新几个表。为此,我一直在网上寻找将表名作为参数传递的方法,所有答案都很复杂和/或抛出错误(如下所示:“Incorrect syntax near 'Table' error shows)

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

这个脚本在显式命名时工作得很好,那么如何参数化表名?

谢谢,

内特

【问题讨论】:

标签: sql sql-server stored-procedures


【解决方案1】:

使用动态 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)

举个例子

【讨论】:

  • 动态 sql 是一个很好的解决方案——对此没有异议。不过,我建议通过 sp_executesql 将其参数化。 couple of advantages--防止sql注入是最大的优势。
  • 很好,我自己对动态 sql(和 sql 时期)还很陌生,但最近在工作中一直在疯狂地使用它。感谢您的链接
  • 我打算编辑我​​的答案以包含 Sp_executesql 但想知道如何添加表名 var,因为它只是表名的最后一个并且仍需要添加到“[ S2].[DELTAS].[dbo]."
【解决方案2】:

关于由于 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,所以这可能有错字。

【讨论】:

    【解决方案3】:

    简短的回答是你不能参数化表名。

    更长的答案是可以通过动态SQL完成你想要的。看起来您正在使用 SQL Server。详情请参阅问题Dynamic SQL - EXEC(@SQL) versus EXEC SP_EXECUTESQL(@SQL)

    然而,将任意表名放入查询中的需求确实不应该是一种代码异味,这表明您的数据库设计存在架构问题,并且可能与您的 E-R 模型有关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多