Hi I am trying to run the following SQL which will pull out table names named SourceDestination by iterating through all databases whose name has 'Pull'.
But I am getting an error at the plus sign near '+@db_name+'.sys.tables. I tried N'' on both sides but I can't seem to get it to work.
It gives this error Msg 102, Level 15, State 1, Line 20 Incorrect syntax near '+'.
Need to know where I am wrong. Thanks for the help.
declare db_names cursor for
select name
from master.sys.databases
where name like 'Pull_%'
declare @db_name varchar(50)
declare @table_name varchar(50)
declare @sql nvarchar(100)
DECLARE @ParmDefinition NVARCHAR(500);
open db_names
fetch next from db_names into @db_name
while @@FETCH_STATUS = 0
begin
print @db_name
-- set @sql = 'select '+@table_name+'=name from '+@db_name+'.sys.tables'
-- set @sql = N'select @table_name=name from @db_name.sys.tables where name = ''SourceDestinations'' '
execute sp_executesql N'select @tbl_name=name from '+@db_name+'.sys.tables where name = ''SourceDestinations'' ', N'@tbl_name varchar(50) OUTPUT', @tbl_name=@table_name OUTPUT
--exec(@sql)o
print @table_name
FETCH NEXT FROM db_names INTO @db_name
end
close db_names
deallocate db_names
You need to build the command string as a seperate step from the sp_executesql
call:
set @sql = N'select @tbl_name=name from '+@db_name+'.sys.tables where name = ''SourceDestinations'' '
execute sp_executesql @sql, N'@tbl_name varchar(50) OUTPUT', @tbl_name=@table_name OUTPUT
EDIT The variable may not be being set by the second iteration.
Try adding
SET @table_name = NULL
after
print @table_name
If all you want to do is print the names of the databases the table is in, your script can be much simpler (I fail to see the point of retrieving the table name and printing it every time - what could it be other than SourceDestinations
?):
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';
SELECT @sql = @sql + 'IF EXISTS (SELECT 1 FROM ' + QUOTENAME(name)
+ '.sys.tables WHERE name = ''SourceDestinations'')
PRINT ''' + name + ''';'
FROM sys.databases
WHERE name LIKE 'PULL_%';
EXEC sp_executesql @sql;
I suspect though that you want to do more with this once you've determined where the actual tables live. Ed is absolutely right, you can't concatenate a string to pass into sp_executesql as you are executing it, you must build it beforehand. This is true for all stored procedure calls, eg you can't say:
EXEC sp_who2 'act' + 'ive';
Even though it should be the same thing as:
EXEC sp_who2 'active';
You seem to know this already, at least to some extent, because you declared a @sql
variable (though you never use it).
I would change your code to:
DECLARE d CURSOR
LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR SELECT name FROM sys.databases
WHERE name LIKE 'Pull_%';
DECLARE
@db_name NVARCHAR(128),
@sql NVARCHAR(MAX);
OPEN d;
FETCH NEXT FROM d INTO @db_name;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @db_name;
SET @sql = N'IF EXISTS (SELECT 1 FROM ' + QUOTENAME(@db_name)
+ '.sys.tables WHERE name = ''SourceDestinations'')
PRINT ''' + @db_name + ''';'
EXEC sp_executesql @sql;
FETCH NEXT FROM d INTO @db_name;
END
CLOSE d;
DEALLOCATE d;
A couple of key points:
varchar(50)
for database/table names. These should be nvarchar(128)
according to the rules for identifiers . SourceDestinations
if someone has inadvertently created one in their own default schema. @sql
string should probably be longer than 100 characters. I typically use MAX
in these cases because the performance difference isn't worth sitting there wondering whether 255 or 1024 etc. will be enough characters.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.