用动态表名和where子句存储过程循环

时间:2018-11-20 11:22:02

标签: sql-server stored-procedures

我正在尝试更新记录并将其审核插入审核表。

为此,存储过程等待上述变量。

@m_obj_id INT, @m_obj_code NVARCHAR(250), @m_f_code NVARCHAR(250), @m_nv NVARCHAR(4000), @m_last_mod_by INTEGER, @table_name SYSNAME, --@where_clause NVARCHAR(4000)

存储过程将这些变量格式化为;

UPDATE @table_name SET @m_f_code=@m_nv WHERE id=@m_obj_id

最后插入审计。

我可以将其用于SELECT CONCAT并复制所有行然后执行。

但是我的目标是不期望用户@m_obj_id并将其替换为@where_clause。并使用此@where_clause来获取ID。

到目前为止,我已经尝试过了

    DECLARE @Sql NVARCHAR(MAX)
    DECLARE @RecordId int = 0
    BEGIN
    SET @SQL = N'
      SELECT @RecordId = MIN(id)
      FROM ' + @table_name + '
      WHERE id > @RecordId AND (' + @where_clause + ')
      IF @RecordId IS NULL BREAK
      SET @m_obj_id = @RecordId'
Exec sp_executesql @sql

但是无法做到这一点。

然后我尝试了类似的方法

DECLARE @RowsToProcess  int
DECLARE @CurrentRow     int
DECLARE @SelectCol1     int

DECLARE @sql NVARCHAR(MAX)
SET @sql = N'
DECLARE @table1 TABLE (RowID int not null primary key identity(1,1), col1 int )  
INSERT into @table1 (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
SET @RowsToProcess=@@ROWCOUNT'
EXEC sp_executesql @sql,
N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

SET @CurrentRow=0
WHILE @CurrentRow<@RowsToProcess
BEGIN
    SET @CurrentRow=@CurrentRow+1
        DECLARE @sql2 NVARCHAR(MAX)
        SET @sql2 = N'
        SET @m_obj_id =
        (SELECT col1
        FROM @table1
        WHERE RowID=@CurrentRow)'
        EXEC sp_executesql @sql2

但仍然没有运气。

我能怎么实现?我正在为此付出更多的努力。 谢谢大家。

2 个答案:

答案 0 :(得分:0)

在sql上实现动态过滤的非动态方式如下:

where id=@m_obj_id or @m_obj_id is null

有关如何在动态和非动态sql之间进行选择的更多详细信息,我建议this article by Erland Sommarskog

答案 1 :(得分:0)

我找到了解决方案。谢谢大家的回应。

我使用了一个临时表,例如

DECLARE @RowsToProcess INTEGER
DECLARE @CurrentRow INTEGER
DECLARE @SelectCol1 INTEGER

CREATE TABLE #tmp (RowID INTEGER NOT NULL PRIMARY KEY IDENTITY(1,1), col1 int)

DECLARE @sql NVARCHAR(MAX)
SET @sql = N'
INSERT into #tmp (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
SET @RowsToProcess=@@ROWCOUNT'
INSERT INTO #tmp
EXEC sp_executesql @sql,
N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

SET @CurrentRow=0
WHILE @CurrentRow<@RowsToProcess
BEGIN
    SET @CurrentRow=@CurrentRow+1
        SET @m_obj_id =
        (SELECT col1
        FROM #tmp
        WHERE RowID=@CurrentRow)

        Do stuff....