需要在sqlserver 2008中使用带动态sql的Update语句

时间:2015-08-04 10:12:34

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

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

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

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

我需要更新一下,以便从@c_name获取动态计数,并填充row_count的{​​{1}}列,以后可以将其置于循环中      这是我尝试过但它没有用的:

dbo.val

我也尝试了以下,但也没有效果

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

有人可以帮我解决一下如何更新目标表的行数吗?

2 个答案:

答案 0 :(得分:0)

请尝试这样的事情:

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

答案 1 :(得分:0)

您不需要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