如何创建一个以表名作为输入的简单存储过程

Posted

技术标签:

【中文标题】如何创建一个以表名作为输入的简单存储过程【英文标题】:How to create a simple stored procedure with table name as an input 【发布时间】:2018-05-02 15:59:08 【问题描述】:

我正在使用 SQL Server 2017,我想创建一个使用单个表名作为输入变量的存储过程。我想要该过程做的就是以各种方式更新该表。这个项目一年做两次,列总是一样的,所以我想把这个当作存储过程来试试,这样就不用每次都高亮几行代码和执行了。

是否有一种简单的方法可以通过更新表的存储过程传递表名(添加列、计算列、替换列中的空值等)。在一个基本示例中,一项任务就是将一列中的空值替换为 0。我不确定如何设置它。我是否也必须声明表中的每一列?

CREATE PROCEDURE updteleform  
    @tablename TABLE
AS
BEGIN
    UPDATE @tablename
    SET Recog = 0
    WHERE Recog IS NULL
END
GO 

【问题讨论】:

听起来你正在处理一个表,所以你还没有真正参数化正确的东西。我认为您应该为每个操作都有一个存储过程,并且每个存储过程都直接引用该表。如果您对不同的表执行相同的操作集,请为该表创建相同的存储过程集。不要把“不要重复自己”看得太认真。 How to take table name as an input parameter to the stored procedure?的可能重复 【参考方案1】:

我假设您要更新物理表。 SQL Server 表变量不是这样工作的,而是一种将瞬态结果集传递给存储过程的方法。如果您的存储过程不这样做,则没有持久性。

如果您要更新同一个表,那么只需编写处理该表的过程即可。

如果您希望使用相同的脚本更新多个表,那么您应该更改您的过程以接受一个字符串参数,该参数将是您希望它处理的表的名称,然后在您的存储过程中使用动态 SQL。

类似

CREATE PROCEDURE updteleform  @tablename sysname
AS
BEGIN

DECLARE @sql NVARCHAR(MAX);

SET @sql = N'
update ' + QUOTENAME(@tablename) + '
set Recog= 0
where Recog is null;';

EXEC sp_executesql @sql;

END
GO 

然后用类似这样的方式调用它:

EXEC updteleform @tablename = 'table1';
EXEC updteleform @tablename = 'table2';
EXEC updteleform @tablename = 'table3';
...

【讨论】:

谢谢 - 这有助于消除一些困惑。是的,我想更新物理表。您是否有任何指示我将如何设置存储过程以使用动态 sql 使用相同的脚本更新不同的表(随着时间的推移)? 我的回答中的例子是如何使用动态 SQL 来做到这一点。 您至少需要将@tablename 与quotename 包装起来,以帮助防止sql 注入。 @user9084595 为什么需要一个存储过程来针对不同数量的表处理所有这些不同的问题?你所有的表都有完全相同的结构吗?操作是否会因表而有所不同,或者对一个表有效但对另一表无效?对任何表执行任何操作的单个存储过程有什么好处? @AaronBertrand 我怀疑他们的表格被客户或类似的东西分开了,他们想要更新所有这些表格。对这种事情的需求对我来说是标准化问题的尖叫。似乎表中的一列而不是几十个相同的表会首先防止这种情况。

以上是关于如何创建一个以表名作为输入的简单存储过程的主要内容,如果未能解决你的问题,请参考以下文章

如何将表名作为参数传递给存储过程?

通过将列和表名作为参数传递来创建 BigQuery 存储过程

存储过程,将表名作为参数传递

在 MySQL 中:如何将表名作为存储过程和/或函数参数传递?

将表名作为参数传递给存储过程

在 azure synapse 存储过程中将表名作为参数传递时将查询结果分配给变量