Reputation: 11
My following code gives error: (SQL Server 2008R2; Fetch two database name in cursor and then insert data to Table1 in two databases)
DECLARE @SQL NVARCHAR(max)
DECLARE @DB VARCHAR(50)
DECLARE CUR_DB CURSOR FAST_FORWARD FOR
SELECT NAME FROM MASTER.SYS.DATABASES
WHERE DATABASE_ID IN ('5', '81')
;
OPEN CUR_DB;
FETCH NEXT FROM CUR_DB INTO @DB;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @SQL = 'INSERT INTO @DB.dbo.Table1 VALUES (100, ''abc'', def'', 0)'
EXEC(@SQL)
FETCH NEXT FROM CUR_DB INTO @DB
END;
CLOSE CUR_DB;
DEALLOCATE CUR_DB;
Error: Msg 102, Level 15, State 1, Line 1 Incorrect syntax near '.'. Msg 102, Level 15, State 1, Line 1 Incorrect syntax near '.'.
Upvotes: 0
Views: 1081
Reputation: 8033
Please try the below script
DECLARE @SQL NVARCHAR(max)
DECLARE @DB VARCHAR(50)
DECLARE CUR_DB CURSOR FAST_FORWARD FOR
SELECT NAME FROM MASTER.SYS.DATABASES
WHERE DATABASE_ID IN ('5', '81');
OPEN CUR_DB;
FETCH NEXT FROM CUR_DB INTO @DB;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @SQL = 'INSERT INTO ['+@DB+'].[dbo].[Table1] VALUES (100,''abc'',''def'', 0)'
EXEC( @SQL)
FETCH NEXT FROM CUR_DB INTO @DB
END;
CLOSE CUR_DB;
DEALLOCATE CUR_DB;
There were 2 Issues in the script:
You were using the parameter name inside the Query string
'INSERT INTO **@DB**.dbo.Table1 VALUES (100, ''abc'', def'', 0)'
this will cause an error because the EXEC statement runs all the statements given inside the brackets as a separate batch and none of the parameters that you declared before that comes outside the scope of the EXEC statement. So Instead change it as follow
SELECT @SQL = 'INSERT INTO **['+@DB+']**.[dbo].[Table1] VALUES (100, ''abc'', ''def'', 0)'
There were 2 single quotes missing before the before the value def
VALUES (100, ''abc'', **def''**, 0)'
So I just added that.
Hope that helps.
Upvotes: 0
Reputation: 33571
Why are you using a cursor for this? You have limited this to only two databases. Why not just code this as two insert statements and forget all the craziness with a cursor. This entire cursor structure is really this simple.
INSERT INTO DataBaseNameForDataBaseID5.dbo.Table1 VALUES (100, 'abc', 'def', 0)
INSERT INTO DataBaseNameForDataBaseID81.dbo.Table1 VALUES (100, 'abc', 'def', 0)
---EDIT---
Since you say you need to do this on more than those two databases you still don't need to resort to cursors for this kind of thing. Take a look at this. It utilizes dynamic sql but doesn't need a loop.
declare @SQL nvarchar(MAX) = N''
select @SQL = @SQL + N'INSERT INTO ' + QuoteName(name) + N'.dbo.Table1 VALUES (100, ''abc'', ''def'', 0);'
from sys.databases
where DATABASE_ID IN (5, 81) --No quotes here, these are integers, not strings
exec sp_executesql @SQL
Upvotes: 0
Reputation: 70638
You aren't concatenating the name of the database in your dynamic SQL:
DECLARE @SQL NVARCHAR(max)
DECLARE @DB VARCHAR(50)
DECLARE CUR_DB CURSOR FAST_FORWARD FOR
SELECT NAME FROM MASTER.SYS.DATABASES
WHERE DATABASE_ID IN ('5', '81')
;
OPEN CUR_DB;
FETCH NEXT FROM CUR_DB INTO @DB;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @SQL = 'INSERT INTO ' + QUOTENAME(@DB) + '.dbo.Table1 VALUES (100, ''abc'', def'', 0)'
EXEC(@SQL)
FETCH NEXT FROM CUR_DB INTO @DB
END;
CLOSE CUR_DB;
DEALLOCATE CUR_DB;
Upvotes: 1