【问题标题】:Need to use Update statement with dynamic sql in sqlserver 2008需要在 sql server 2008 中使用带有动态 sql 的 Update 语句
【发布时间】:2015-08-04 10:12:34
【问题描述】:

我有一个目标表 dbo.val,其中包含三列:table_schematable_namerow_count,其中架构和名称已填充,并且特定数据库的相应行数设置为零。
我需要每个表名的行数,但不能使用系统表来计算行数,因为它们有时可能会提供不准确的数据。

我使用游标从 INFORMATION_SCHEMA.TABLES 获取表和架构名称以填充到 @tb_schema@tb_table 变量中,并使用第三个变量 @c_name 来合并两者

set @c_name = @tb_schema + '.' + @tb_name; 

我需要一个更新语句从@c_name 获取动态计数并填充dbo.valrow_count 列,稍后可以将其放入循环中
这是我尝试过的,但没有奏效:

 update dbo.val set row_count = Exec ('select COUNT(*) from ' + @full_name)
 where table_schema = @tb_schema and table_name =@tb_name  ;

我也尝试了以下方法,但效果不佳

declare @catch numeric (20)
select @catch = Exec ('select COUNT(*) from ' + @full_name) ;
update dbo.validate set cnt = @catch
where tb_schema = @tb_schema and tb_name =@tb_name  ;

谁能帮帮我,如何更新我的目标表的行数?

【问题讨论】:

    标签: sql-server sql-server-2008 sql-update dynamic-sql


    【解决方案1】:

    请尝试以下方法:

    DECLARE @sqlCommand nvarchar(1000)
    DECLARE @full_name varchar(75)
    DECLARE @row_count int
    
    SET @full_name = @tb_schema + '.' + @tb_name; 
    SET @sqlCommand = 'SELECT @cnt=COUNT(*) FROM '+ @full_name 
    EXECUTE sp_executesql @sqlCommand, N'@cnt int OUTPUT', @cnt=@row_count OUTPUT
    
    update dbo.val 
    set    row_count = @row_count 
    where  table_schema = @tb_schema 
      and  table_name =@tb_name
    

    您还需要创建游标以从 dbo.val 获取 @tb_schema@tb_name

    【讨论】:

    • 您需要光标方面的帮助吗?
    【解决方案2】:

    您不需要CURSOR 来执行此操作。方法如下:

    首先,让我们创建示例数据。

    --Table to UPDATE
    CREATE TABLE validate(
        tb_schema   VARCHAR(256),
        tb_Name     VARCHAR(256),
        cnt         INT
    )
    INSERT INTO validate VALUES
    ('dbo', 'TableA', 0), ('dbo', 'TableB', 0);
    
    --Sample TableA with 50 rows
    CREATE TABLE TableA(id int);
    INSERT INTO TableA
        SELECT TOP(50) ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
        FROM sys.columns a
    
    --Sample TableB with 20 rows
    CREATE TABLE TableB(id int);
    INSERT INTO TableB
        SELECT TOP(20) ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
        FROM sys.columns a
    

    这是使用临时表的解决方案:

    --Temporary table to hold the row counts of each table
    CREATE TABLE #temp(
        tb_schema   VARCHAR(256),
        tb_Name     VARCHAR(256),
        cnt         INT
    )
    
    --Generate your dynamic SQL here
    DECLARE @sql NVARCHAR(MAX) = ''
    
    SELECT @sql = 'INSERT INTO #temp(tb_schema, tb_Name, cnt)' + CHAR(10)
    
    SELECT @sql = @sql + 
    'SELECT ''' + SCHEMA_NAME(schema_id) + ''', ''' + name + ''', COUNT(*) FROM ' + QUOTENAME(name) + ' UNION ALL ' + CHAR(10)
    FROM sys.tables
    WHERE name <> 'validate'
    
    --Remove the last occurence of UNION ALL
    SELECT @sql = LEFT(@sql, LEN(@sql) - 11)
    
    --Check the generated SQL
    PRINT @sql
    EXEC (@sql)
    
    --Update dbo.validate from values in #temp
    UPDATE v
        SET cnt = t.cnt
    FROM dbo.validate v
    INNER JOIN #temp t
        ON t.tb_schema = v.tb_schema
        AND t.tb_name = v.tb_name
    
    --Check result
    SELECT * FROM validate
    

    【讨论】:

    • 非常感谢菲利克斯!没想到是这样的!
    • 没问题。很高兴能帮上忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多