I need to test if a table exists in a linked server, where linked server is a parameter (it has to be), that's why I'm using exec method. I tried many ways but I didn't succeed.
Declare #LinkedServerName varchar(50)
Declare #DS varchar(50)
Declare #username varchar(50)
Declare #pswd varchar(12)
Declare #TableExists int
Set #DS = 'test\TestDB'
Set #LinkedServerName = 'LinkedServerAutoAddDrop'
Set #username = 'ua'
Set #pswd = 'pass'
Set #TableExists = 0
if not exists(select * from sys.servers where name = #LinkedServerName)
BEGIN
EXEC sp_addlinkedserver
#server=#LinkedServerName,
#srvproduct='',
#provider='SQLNCLI',
#datasrc=#DS
EXEC sp_addlinkedsrvlogin #LinkedServerName, N'false', NULL, #username, #pswd
exec sp_serveroption #server=#LinkedServerName, #optname='rpc', #optvalue='TRUE'
exec sp_serveroption #server=#LinkedServerName, #optname='rpc out', #optvalue='TRUE'
END
exec('IF (EXISTS (SELECT * FROM OPENQUERY([' + #LinkedServerName + '], ''select * from LinkedDB.INFORMATION_SCHEMA.TABLES Where TABLE_NAME = ''''TableName'''''')))
BEGIN
exec (''Set ' + #TableExists + ' = 1'')
END')
IF (#TableExists = 1)
BEGIN
exec('Insert Into ...')
END
I personally would use sp_executesql along with an output parameter for this:
DECLARE #SQL NVARCHAR(MAX) = ''
DECLARE #TableExists BIT;
SET #SQL = 'SELECT #TableExists = CASE WHEN TableExists = 0 THEN 0 ELSE 1 END
FROM OPENQUERY(' + QUOTENAME(#LinkedServerName)
+ ', ''SELECT TableExists = COUNT(*)
FROM LinkedDB.INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = ''''TableName'''''');';
EXECUTE sp_executesql #SQL, N'#TableExists BIT OUTPUT', #TableExists OUT;
IF (#TableExists = 1)
BEGIN
-- DO SOMETHING
END;
TO Check If Column Exist Or Not I Use following:
If Returns 1 then COLUMN EXIST Else If 0 then COLUMN DOSE NOT EXIST
If Database On same Server then Provide #ServerName as Empty Field ('')
CREATE PROCEDURE [dbo].[udsp_CheckIfColumExist](#DBName Varchar(1000),#ColName Varchar(1000),#TableName Varchar(1000),#ServerName Varchar(1000))AS
DECLARE #SqlStr VARCHAR(MAX) = ''
IF #ServerName <> ''
SET #ServerName = '['+#ServerName+'].'
SET #SqlStr ='SELECT COUNT(1) IsExist FROM '+ #ServerName + #DBName+'.sys.columns
c join '+ #ServerName + #DBName +'.sys.tables t on t.OBJECT_ID = c.OBJECT_ID
WHERE c.name = N'''+#ColName +''' AND t.name = N''' +#TableName +''''
EXEC(#SqlStr)
If you want to perform same check on table remove column part from query.
Related
I have 2 table (same name) on 2 different database
I want compare these table, this is my procedure
ALTER PROCEDURE COUNTCOLUMN
#TABLENAME NVARCHAR(MAX),
#DATABASENAME1 NVARCHAR(MAX),
#DATABASENAME2 NVARCHAR(MAX)
AS
BEGIN
DECLARE #COLNAME NVARCHAR(MAX)
DECLARE #ROWCOUNT INT
DECLARE #ROWCOUNT2 INT
DECLARE #NUMB1 INT
DECLARE #NUMB2 INT
DECLARE #SQLQUERY NVARCHAR(MAX)
DECLARE #SQLQUERY2 NVARCHAR(MAX)
DECLARE #SQLQUERY3 NVARCHAR(MAX)
DECLARE #SQLQUERY4 NVARCHAR(MAX)
DECLARE #SQLQUERY5 NVARCHAR(MAX)
DECLARE #SQLQUERY6 NVARCHAR(MAX)
SET #SQLQUERY = 'SELECT #NUMBER = COUNT(*) FROM information_schema.columns WHERE table_name = '+N'#TESTTB'+''
SET #SQLQUERY2 = 'USE ' + #DATABASENAME1
SET #SQLQUERY3 = 'USE ' + #DATABASENAME2
EXECUTE sp_executesql #SQLQUERY2
EXECUTE sp_executesql #SQLQUERY, N'#TESTTB NVARCHAR(MAX), #NUMBER INT OUTPUT',#TESTTB = #TABLENAME ,#NUMBER = #NUMB1 OUTPUT
EXECUTE sp_executesql #SQLQUERY3
EXECUTE sp_executesql #SQLQUERY, N'#TESTTB NVARCHAR(MAX), #NUMBER INT OUTPUT',#TESTTB = #TABLENAME ,#NUMBER = #NUMB2 OUTPUT
IF(#NUMB1 <= #NUMB2)
BEGIN
DECLARE #NUMB INT
SET #NUMB = 1
WHILE (#NUMB <= #NUMB1)
BEGIN
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'TEMP1'))
BEGIN
DROP TABLE TEMP1
END
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'TEMP2'))
BEGIN
DROP TABLE TEMP2
END
ELSE
BEGIN
SET #SQLQUERY4 = 'SELECT #COL_NAME = COL_NAME(OBJECT_ID(#TABLENAME), #NUMB)'
EXECUTE sp_executesql #SQLQUERY2
EXECUTE sp_executesql #SQLQUERY4, N'#TABLENAME NVARCHAR(MAX),#NUMB INT, #COL_NAME NVARCHAR(MAX) OUTPUT', #TABLENAME = #TABLENAME,#NUMB=#NUMB, #COL_NAME = #COLNAME OUTPUT
SET #SQLQUERY5 = 'SELECT '+ #COLNAME + ' INTO TEST_DB..TEMP1 FROM ' + #TABLENAME
EXECUTE sp_executesql #SQLQUERY2
EXECUTE sp_executesql #SQLQUERY5
EXECUTE sp_executesql #SQLQUERY3
EXECUTE sp_executesql #SQLQUERY4, N'#TABLENAME NVARCHAR(MAX),#NUMB INT, #COL_NAME NVARCHAR(MAX) OUTPUT', #TABLENAME = #TABLENAME,#NUMB=#NUMB, #COL_NAME = #COLNAME OUTPUT
SET #SQLQUERY6 = 'SELECT ' + #COLNAME +' INTO TEST_DB..TEMP2 FROM '+ #TABLENAME
EXECUTE sp_executesql #SQLQUERY3
EXECUTE sp_executesql #SQLQUERY6
SELECT #ROWCOUNT = COUNT(*) FROM TEMP1
SELECT #ROWCOUNT2 = COUNT(*) FROM TEMP2
IF(#ROWCOUNT != #ROWCOUNT2)
BEGIN
PRINT N'NUMBER OF ROWS ARE NOT EQUAL';
BREAK
END
ELSE IF (#NUMB > #NUMB1)
BREAK
ELSE
BEGIN
SELECT * FROM TEST_DB..TEMP1
EXCEPT
SELECT * FROM TEST_DB..TEMP2
SET #NUMB = #NUMB + 1;
CONTINUE
END
END
END
END
END
It should be like this TEMP1 <--TEST_DB..TESTTABLE, TEMP2 <--TEST_DB2..TESTTABLE
But TEMP1 , TEMP2 always have the same values as TESTTABLE from the first database (TEST_DB )
It seem like I can't switch between two databases in procedure so I try to run it separate but still not work
I am trying to execute this query:
declare #tablename varchar(50)
set #tablename = 'test'
select * from #tablename
This produces the following error:
Msg 1087, Level 16, State 1, Line 5
Must declare the table variable "#tablename".
What's the right way to have the table name populated dynamically?
For static queries, like the one in your question, table names and column names need to be static.
For dynamic queries, you should generate the full SQL dynamically, and use sp_executesql to execute it.
Here is an example of a script used to compare data between the same tables of different databases:
Static query:
SELECT * FROM [DB_ONE].[dbo].[ACTY]
EXCEPT
SELECT * FROM [DB_TWO].[dbo].[ACTY]
Since I want to easily change the name of table and schema, I have created this dynamic query:
declare #schema sysname;
declare #table sysname;
declare #query nvarchar(max);
set #schema = 'dbo'
set #table = 'ACTY'
set #query = '
SELECT * FROM [DB_ONE].' + QUOTENAME(#schema) + '.' + QUOTENAME(#table) + '
EXCEPT
SELECT * FROM [DB_TWO].' + QUOTENAME(#schema) + '.' + QUOTENAME(#table);
EXEC sp_executesql #query
Since dynamic queries have many details that need to be considered and they are hard to maintain, I recommend that you read: The curse and blessings of dynamic SQL
Change your last statement to this:
EXEC('SELECT * FROM ' + #tablename)
This is how I do mine in a stored procedure. The first block will declare the variable, and set the table name based on the current year and month name, in this case TEST_2012OCTOBER. I then check if it exists in the database already, and remove if it does. Then the next block will use a SELECT INTO statement to create the table and populate it with records from another table with parameters.
--DECLARE TABLE NAME VARIABLE DYNAMICALLY
DECLARE #table_name varchar(max)
SET #table_name =
(SELECT 'TEST_'
+ DATENAME(YEAR,GETDATE())
+ UPPER(DATENAME(MONTH,GETDATE())) )
--DROP THE TABLE IF IT ALREADY EXISTS
IF EXISTS(SELECT name
FROM sysobjects
WHERE name = #table_name AND xtype = 'U')
BEGIN
EXEC('drop table ' + #table_name)
END
--CREATES TABLE FROM DYNAMIC VARIABLE AND INSERTS ROWS FROM ANOTHER TABLE
EXEC('SELECT * INTO ' + #table_name + ' FROM dbo.MASTER WHERE STATUS_CD = ''A''')
Use:
CREATE PROCEDURE [dbo].[GetByName]
#TableName NVARCHAR(100)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #sSQL nvarchar(500);
SELECT #sSQL = N'SELECT * FROM' + QUOTENAME(#TableName);
EXEC sp_executesql #sSQL
END
You can't use a table name for a variable. You'd have to do this instead:
DECLARE #sqlCommand varchar(1000)
SET #sqlCommand = 'SELECT * from yourtable'
EXEC (#sqlCommand)
You'll need to generate the SQL content dynamically:
declare #tablename varchar(50)
set #tablename = 'test'
declare #sql varchar(500)
set #sql = 'select * from ' + #tablename
exec (#sql)
Use sp_executesql to execute any SQL, e.g.
DECLARE #tbl sysname,
#sql nvarchar(4000),
#params nvarchar(4000),
#count int
DECLARE tblcur CURSOR STATIC LOCAL FOR
SELECT object_name(id) FROM syscolumns WHERE name = 'LastUpdated'
ORDER BY 1
OPEN tblcur
WHILE 1 = 1
BEGIN
FETCH tblcur INTO #tbl
IF ##fetch_status <> 0
BREAK
SELECT #sql =
N' SELECT #cnt = COUNT(*) FROM dbo.' + quotename(#tbl) +
N' WHERE LastUpdated BETWEEN #fromdate AND ' +
N' coalesce(#todate, ''99991231'')'
SELECT #params = N'#fromdate datetime, ' +
N'#todate datetime = NULL, ' +
N'#cnt int OUTPUT'
EXEC sp_executesql #sql, #params, '20060101', #cnt = #count OUTPUT
PRINT #tbl + ': ' + convert(varchar(10), #count) + ' modified rows.'
END
DEALLOCATE tblcur
You need to use the SQL Server dynamic SQL:
DECLARE #table NVARCHAR(128),
#sql NVARCHAR(MAX);
SET #table = N'tableName';
SET #sql = N'SELECT * FROM ' + #table;
Use EXEC to execute any SQL:
EXEC (#sql)
Use EXEC sp_executesql to execute any SQL:
EXEC sp_executesql #sql;
Use EXECUTE sp_executesql to execute any SQL:
EXECUTE sp_executesql #sql
Declare #tablename varchar(50)
set #tablename = 'Your table Name'
EXEC('select * from ' + #tablename)
Also, you can use this...
DECLARE #SeqID varchar(150);
DECLARE #TableName varchar(150);
SET #TableName = (Select TableName from Table);
SET #SeqID = 'SELECT NEXT VALUE FOR ' + #TableName + '_Data'
exec (#SeqID)
Declare #fs_e int, #C_Tables CURSOR, #Table varchar(50)
SET #C_Tables = CURSOR FOR
select name from sysobjects where OBJECTPROPERTY(id, N'IsUserTable') = 1 AND name like 'TR_%'
OPEN #C_Tables
FETCH #C_Tables INTO #Table
SELECT #fs_e = sdec.fetch_Status FROM sys.dm_exec_cursors(0) as sdec where sdec.name = '#C_Tables'
WHILE ( #fs_e <> -1)
BEGIN
exec('Select * from ' + #Table)
FETCH #C_Tables INTO #Table
SELECT #fs_e = sdec.fetch_Status FROM sys.dm_exec_cursors(0) as sdec where sdec.name = '#C_Tables'
END
I have a stored procedure which is supposed to return a result set from a table filtered according to parameters provided.
UPDATE
alter procedure Proc_CheckExchange
#Flag varchar(3),
#symbol varchar(13)=null,
#exchange char(3)=null,
#limit money=null,
#chargerate numeric(18,4)=null,
#ChgType char(2)=null,
#IsActive int=null,
#Mkrid varchar(11)=null,
#statecode varchar(4) =null
as
declare #sql nvarchar(max)
set #sql = N'select * from Tbl_StampDutyException1 where 1 = 1'
if(#Flag='CHK')
begin
if len(isnull(#exchange, '')) > 0
set #sql = #sql + N'and exchange=#exchange'+ cast(#exchange as nvarchar(100))
if len(isnull(#symbol, '')) > 0
set #sql = #sql + N'and symbol=#symbol'+ cast(#symbol as nvarchar(100))
if len(isnull(#limit, '')) > 0
set #sql = #sql + N'and limit=#limit'+ cast(#limit as nvarchar(100))
if len(isnull(#chargerate, '')) > 0
set #sql = #sql + N'and chargerate=#chargerate'+ cast(#chargerate as nvarchar(100))
if len(isnull(#ChgType, '')) > 0
set #sql = #sql + N'and ChgType=#ChgType'+ cast(#ChgType as nvarchar(100))
if len(isnull(#IsActive, '')) > 0
set #sql = #sql + N'and IsActive=#IsActive'+ cast(#IsActive as nvarchar(100))
if len(isnull(#statecode, '')) > 0
set #sql = #sql + N'and statecode=#statecode'+ cast(#statecode as nvarchar(100))
exec (#sql)
end
if (#Flag='ALL')
begin
select * from Tbl_StampDutyException1
end
UPDATE 1
alter procedure Proc_CheckExchange
#Flag varchar(3),
#symbol varchar(13)=null,
#exchange char(3)=null,
#limit money=null,
#chargerate numeric(18,4)=null,
#ChgType char(2)=null,
#IsActive int=null,
#Mkrid varchar(11)=null,
#statecode int =null
as
declare #sql nvarchar(max)
set #sql = N'select * from Tbl_StampDutyException1 where 1 = 1'
if(#Flag='CHK')
begin
if len(isnull(#exchange, '')) > 0
set #sql = #sql + N' and exchange = #exchange'
if len(isnull(#limit, '')) > 0
set #sql = #sql + N' and limit = #limit'
if len(isnull(#chargerate, '')) > 0
set #sql = #sql + N' and chargerate = #chargerate'
if len(isnull(#ChgType, '')) > 0
set #sql = #sql + N' and ChgType = #ChgType'
if len(isnull(#IsActive, '')) > 0
set #sql = #sql + N' and IsActive = #IsActive'
if len(isnull(#statecode, '')) > 0
set #sql = #sql + N' and statecode = #statecode'
if len(isnull(#symbol, '')) > 0
set #sql = #sql + N' and symbol = #symbol'
declare #params as nvarchar(max) = N'#Flag varchar(3),
#symbol varchar(13),
#exchange char(3),
#limit money,
#chargerate numeric(18,4),
#ChgType char(2),
#IsActive int,
#Mkrid varchar(11),
#statecode varchar(4)'
print #sql
--EXECUTE sp_executesql #sql, #params, #Flag, #symbol, #exchange, #limit, #chargerate, #ChgType, #IsActive, #Mkrid, #statecode
end
I am trying to create a stored procedure in which there will be as many conditions in WHERE clause as passed to the stored procedure. I hope I am clear about what I am trying to achieve. I am getting error Error converting data type varchar to numeric.
I think that a good solution would be this one
SELECT * from dbo.Clients
WHERE
(#param1 IS NULL OR field1 = #param1)
AND (#param2 IS NULL OR field2 = #param2)
With this approach the statement will not be re-processed (execution plan) by the server every time you execute the query.
What you could do is to rewrite your stored proc using dynamic SQL and include parts of where clause only if parameters are defined, e.g. replace the body with
declare #sql nvarchar(max)
set #sql = N'select * from Tbl_StampDutyException1 where 1 = 1'
if len(isnull(#exchange, '')) > 0
set #sql = #sql + N' and exchange = ' + cast(#exchange as nvarchar(100))
-- add all parameters; you need to cast them to nvarchar if they have other type
exec (#sql)
As an improvement, you can use sp_executesql to execute dynamic SQL. See here on how to use it. In this case, the code will be:
declare #sql nvarchar(max)
set #sql = N'select * from Tbl_StampDutyException1 where 1 = 1'
if len(isnull(#exchange, '')) > 0
set #sql = #sql + N' and exchange = #exchange'
-- add all parameters;
declare #params as nvarchar(max) = N'#Flag varchar(3),
#symbol varchar(13),
#exchange char(3),
#limit money,
#chargerate numeric(18,4),
#ChgType char(2),
#IsActive int,
#Mkrid varchar(11),
#statecode varchar(4)'
EXECUTE sp_executesql #sql, #params, #Flag, #symbol, #exchange, #limit, #chargerate, #ChgType, #IsActive, #Mkrid, #statecode
By the way, don't use select * in stored procedures, it's not a good practice. List all the columns you want to return. Otherwise, if the table definition changes, you will get different result to what it was previously.
What I guess you need is a CONDITIONAL WHERE CLAUSE approach, have provided the sample script below, you need to convert all the IF conditions to a CASE and you then you can combine all the conditions into a single SELECT statement:
SELECT * FROM Tbl_StampDutyException1
WHERE
exchange = CASE WHEN #exchange='' or #exchange is null THEN exchange ELSE #exchange END
AND symbol = Case when #symbol='' or #symbol is null THEN symbol ELSE symbol
AND *so on.....*
I have a stored procedure which I have to rewrite using sp_executesql. I want to use sp_executesql instead of exec because of performance issue on my SQL Server instance.
Here is my code:
ALTER PROCEDURE [dbo].[sp_TestSp1]
#Type1 VARCHAR(256)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sqlCommand varchar(2000) = ''
DECLARE #columnList varchar(1000) = ''
DECLARE #dynamicSql varchar(1000) = ''
IF (#Type1 IS NOT NULL )
BEGIN
SET #dynamicSql = #dynamicSql + 'AND tbl1.DTypeID IN ( '+ #Type1+ ' )'
END
SET #columnList = 'SELECT DISTINCT tbl2.ID, Name AS PName '
SET #sqlCommand = #columnList
+ ' FROM tbl1 '
+ ' INNER JOIN tbl3 ON tbl1.NID= tbl3.NID '
+ ' INNER JOIN tbl4 ON tbl3.DID = tbl4.DID '
+ ' WHERE TT=1 AND IsActive=1 AND tbl1.DTypeID IN (1,3,5)'
+ #dynamicSql
EXEC (#sqlCommand)
Replace your EXEC (#sqlCommand) statement with the following.
EXECUTE sp_executesql #sqlCommand
TechNet Link
I was wondering if someone could help me with creating a while loop to iterate through several databases to obtain data from one table from two columns. this is was I have done so far. nothing works because i do not know how to make the select statement work through each database with regards to the table that I am querying from each database (dbo.tbldoc)
DECLARE #Loop int
DECLARE #DBName varchar(300)
DECLARE #SQL varchar(max)
DECLARE #tableName VARCHAR(255)
SET #Loop = 1
SET #DBName = ''
WHILE #Loop = 1
BEGIN
SELECT [name] FROM sys.databases
WHERE [name] like 'z%' and create_date between '2010-10-17' and '2011-01-15'
ORDER BY [name]
SET #Loop = ##ROWCOUNT
IF #Loop = 0
BREAK
SET #SQL = ('USE ['+ #DBNAME +']')
IF EXISTS(SELECT [name] FROM sys.tables WHERE name != 'dbo.tbldoc' )
BEGIN
SELECT SUM(PGCOUNT), CREATED FROM **dbo.tbldoc**
END
ELSE
--BEGIN
PRINT 'ErrorLog'
END
I would consider sp_MSForEachDB which is a lot easier...
Edit:
EXEC sp_MSForEachDB 'USE [?]; IF DB_NAME() LIKE ''Z%%''
BEGIN
END
'
CREATE TABLE #T
(dbname sysname NOT NULL PRIMARY KEY,
SumPGCOUNT INT,
CREATED DATETIME)
DECLARE #Script NVARCHAR(MAX) = ''
SELECT #Script = #Script + '
USE ' + QUOTENAME(name) + '
IF EXISTS(SELECT * FROM sys.tables WHERE OBJECT_ID=OBJECT_ID(''dbo.tbldoc''))
INSERT INTO #T
SELECT db_name() AS dbname, SUM(PGCOUNT) AS SumPGCOUNT, CREATED
FROM dbo.tbldoc
GROUP BY CREATED;
'
FROM sys.databases
WHERE state=0 AND user_access=0 and has_dbaccess(name) = 1
AND [name] like 'z%' and create_date between '2010-10-17' and '2011-01-15'
ORDER BY [name]
IF (##ROWCOUNT > 0)
BEGIN
--PRINT #Script
EXEC (#Script)
SELECT * FROM #T
END
DROP TABLE #T
My code to search for data from more than one database would be:
use [master]
go
if object_id('tempdb.dbo.#database') is not null
drop TABLE #database
go
create TABLE #database(id INT identity primary key, name sysname)
go
set nocount on
insert into #database(name)
select name
from sys.databases
where name like '%tgsdb%' --CHANGE HERE THE FILTERING RULE FOR YOUR DATABASES!
and source_database_id is null
order by name
Select *
from #database
declare #id INT, #cnt INT, #sql NVARCHAR(max), #currentDb sysname;
select #id = 1, #cnt = max(id)
from #database
while #id <= #cnt
BEGIN
select #currentDb = name
from #database
where id = #id
set #sql = 'select Column1, Column2 from ' + #currentDb + '.dbo.Table1'
print #sql
exec (#sql);
print '--------------------------------------------------------------------------'
set #id = #id + 1;
END
go
DECLARE #Loop int
DECLARE #MaxLoop int
DECLARE #DBName varchar(300)
DECLARE #SQL varchar(max)
SET #Loop = 1
SET #DBName = ''
set nocount on
SET #MaxLoop = (select count([name]) FROM sys.databases where [name] like 'Z%')
WHILE #Loop <= #MaxLoop
BEGIN
SET #DBName = (select TableWithRowsNumbers.name from (select ROW_NUMBER() OVER (ORDER by [name]) as Row,[name] FROM sys.databases where [name] like 'Z%' ) TableWithRowsNumbers where Row = #Loop)
SET #SQL = 'USE [' + #DBName + ']'
exec (#SQL)
...
...
set #Loop = #Loop + 1
END
***Note: I didn't add the check if exists here.
I ended up writing one last week on the fly for some stuff I was doing.
Blog post here:
http://tsells.wordpress.com/2012/02/14/sql-server-database-iterator/
Here is the code.
SET NOCOUNT ON
GO
use master
go
Declare
#dbname nvarchar(500),
#variable1 int,
#variable2 int,
#variable3 int,
#totaldb int = 0,
#totaldbonserver int = 0,
#totaldbwithmatches int = 0
-- Get non system databases
Declare mycursor CURSOR for select name, database_id from SYS.databases where database_id > 4 order by name desc
open mycursor
fetch next from mycursor into #dbname, #variable1
while (##FETCH_STATUS <> -1)
BEGIN
DECLARE #ParmDefinition NVARCHAR(500)
Declare #mysql nvarchar(500) = 'select #variable2OUT = COUNT(*) from [' + #dbname + '].INFORMATION_SCHEMA.TABLES where Upper(TABLE_NAME) like ''MyTable''';
SET #ParmDefinition = N'#variable2OUT int OUTPUT'
set #totaldbonserver = #totaldbonserver + 1
Execute sp_executesql #mysql, #ParmDefinition, #variable2 OUTPUT
if #variable2 = 1
BEGIN
DECLARE #ParmDefinition2 NVARCHAR(500)
Declare #mysql2 nvarchar(500) = 'select #variable2OUT = COUNT(*) from [' + #dbname + '].dbo.MyTable';
SET #ParmDefinition2 = N'#variable2OUT int OUTPUT'
Execute sp_executesql #mysql2, #ParmDefinition2, #variable3 OUTPUT
set #totaldb = #totaldb + 1
if #variable3 > 1
BEGIN
Print #dbname + ' matched the criteria'
set #totaldbwithmatches = #totaldbwithmatches + 1
END
ELSE
Select 1
END
fetch next from mycursor into #dbname, #variable1
END
PRINT 'Total databases on server: '
Print #totaldbonserver
PRINT 'Total databases tested () : '
Print #totaldb
PRINT 'Total databases with matches: '
Print #totaldbwithmatches
CLOSE mycursor
DEALLOCATE mycursor
This doesn't use a loop. Hope this helps!
Note that "TABLE_OWNER" is that same as "SCHEMA Owner" and "TABLE_TYPE" will identify if the item is a table OR view.
--This will return all tables, table owners and table types for all database(s) that are NOT 'Offline'
--Offline database information will not appear
Declare #temp_table table(
DB_NAME varchar(max),
TABLE_OWNER varchar(max),
TABLE_NAME varchar(max),
TABLE_TYPE varchar(max),
REMARKS varchar(max)
)
INSERT INTO #temp_table (DB_NAME, TABLE_OWNER, TABLE_NAME, TABLE_TYPE,REMARKS)
EXECUTE master.sys.sp_MSforeachdb 'USE [?]; EXEC sp_tables'
SELECT DB_NAME, TABLE_OWNER, TABLE_NAME, TABLE_TYPE
FROM #temp_table
--Uncomment below if you are seaching for 1 database
--WHERE DB_NAME = '<Enter specific DB Name>'
--For all databases other than 'System Databases'
WHERE DB_NAME not in ('master','model','msdn','tempdb')
order by 1,2,3
You don't have to use a "USE DATABASE" statement. You can select from the particular database table by using a 3 part identifier as in:
select * from MyDatabase.dbo.MyTable