TableA exists in all 4 DBs, run this,
Use DB1
go
select CurrentDB=DB_NAME(), * From DB1..TableA union all
select CurrentDB=DB_NAME(), * From DB2..TableA union all
select CurrentDB=DB_NAME(), * From DB3..TableA union all
select CurrentDB=DB_NAME(), * From DB4..TableA
always got CurrentDB ='DB1'. is there a Simple way to get DB2,3,4 when the rows are pulling from non-DB1?
Trying to avoid hard code.
Create the same view in each database that returns the value of DB_NAME() as a column. Then, in the union, the each row will include the database name.
Try this
Use Master
set NOCOUNT ON;
Declare #db_name Varchar(12)
Declare #sql Varchar(1000)
Declare db_cursor CURSOR FOR
SELECT [name]
FROM sys.databases Where [name] like 'DB[123456789]'
Open db_cursor
Fetch Next FROM db_cursor INTO #db_name
if ##FETCH_STATUS = 0
begin
Select #sql = 'select ''' + #db_name + ''', * From ' + #db_name + '..TableA'
Fetch Next FROM db_cursor INTO #db_name
While ##FETCH_STATUS = 0
begin
select #sql = #sql + ' Union all select ''' +
#db_name + ''', * From ' + #db_name + '..TableA'
Fetch NEXT FROM db_cursor INTO #db_name
end
exec #sql
end
Close db_cursor
Deallocate db_cursor
Not tested, but basic idea is get all the matching db names. Build the sql statement, then exec it.
Related
Is it possible to update multiple tables from a query result?
I've tried using a cursor. But it's still not working.
Here's the code :
DECLARE #TableName VARCHAR(MAX)
DECLARE db_cursor CURSOR FOR
SELECT TABLE_NAME
FROM information_schema.columns
WHERE column_name = 'Code1';
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
UPDATE #TableName
SET Code1 = Code + '_' + Type
FETCH NEXT FROM db_cursor INTO #TableName
END
CLOSE db_cursor
DEALLOCATE db_cursor
Hypothesis
I suppose that OP is trying to dynamically build and execute SQL-code for all tables that have column Code1
Solution
Solution (one of many) could be:
Build cursor of created SQL-expressions
In cycle exec created expressions
Example code
DECLARE #sql_code varchar(max)
DECLARE code_cursor CURSOR FOR
SELECT DISTINCT
'UPDATE '+ TABLE_NAME + ' SET Code1= Code + ''_'' + Type;' AS SQL_CODE
FROM
information_schema.columns -- WHERE column_name = 'Code1';
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #sql_code
WHILE ##FETCH_STATUS = 0
BEGIN
exec(#sql_code)
FETCH NEXT FROM db_cursor INTO #TableName
END
CLOSE db_cursor
DEALLOCATE db_cursor
Caution
I did not tested it (of cause - I don't have similar DB) - so be careful.
Update
It's even simpler would be to modify OP code like this:
DECLARE #TableName VARCHAR(MAX)
DECLARE db_cursor CURSOR
FOR SELECT DISTINCT TABLE_NAME -- note DISTINCT here
FROM information_schema.columns WHERE column_name = 'Code1';
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC('UPDATE '+ #TableName + ' SET Code1 = Code + ''_'' + Type') -- note EXEC here
FETCH NEXT FROM db_cursor INTO #TableName
END
CLOSE db_cursor
DEALLOCATE db_cursor
I'm looking to select from multiple tables (MainTbl) but it will be based on the result set (StateTbl) of which tables would be pulled.
MainTables dbo.TABLE_MO, dbo.TABLE_CA, dbo.TABLE_AL, dbo.TABLE_MI
Only looking to pull based on resultset StateTbl MO, CA, WA
Declare #Loop_Count int = 0
DECLARE #State varchar(2)
DECLARE #SQL varchar(max)
DECLARE db_cursor CURSOR FOR SELECT State FROM StateTbl
OPEN db_cursor
FETCH db_cursor INTO #State
WHILE (##FETCH_STATUS = 0)
BEGIN
SET #SQL =
'
dbo.TABLE_'+ #State +'
'
EXEC(#SQL)
SET #Loop_Count = #Loop_Count + 1
FETCH db_cursor INTO #SQL
END
CLOSE db_cursor
DEALLOCATE db_cursor
Instead of a loop you can leverage dynamic and the StateTbl to build your dynamic sql. Something like this.
declare #SQL nvarchar(max) = ''
select 'select * from TABLE_' + [State] + ' UNION ALL '
from StateTbl
select #SQL = left(#SQL, len(#SQL) - 10)
select #SQL
--uncomment the line below when you satisfied the dynamic sql is written the way you want it.
--exec sp_executesql #SQL
I have created a cursor which iterates through all the databases and displays the 1 record per database.
I would like the records to be inserted into 1 table where I can view it. The query may change which is why I don't want to create the table structure for a specific query and insert it. I wanted to use the "select into" clause but that will fail on the second time the cursor runs
DECLARE #DB_Name varchar(100)
DECLARE #Command nvarchar(200)
DECLARE database_cursor CURSOR FOR SELECT name FROM #DBNAME
OPEN database_cursor
FETCH NEXT FROM database_cursor INTO #DB_Name
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #Command = 'use [' + #DB_Name + '] Select '''+ #DB_Name + ''' ,'+
--Enter query below
'* from authentication where username like ''%clair#indicater%'' and password = ''Rohan2410'''
-- print #Command
EXEC sp_executesql #Command
FETCH NEXT FROM database_cursor INTO #DB_Name
END
CLOSE database_cursor
DEALLOCATE database_cursor
You should better use INSERT INTO ... instead of SELECT INTO, something like this:
DECLARE #DB_Name varchar(100)
DECLARE #Command nvarchar(200)
DECLARE database_cursor CURSOR FOR SELECT name FROM #DBNAME
OPEN database_cursor
FETCH NEXT FROM database_cursor INTO #DB_Name
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #Command = 'use [' + #DB_Name + ']
IF OBJECT_ID(''tempdb..##output'') IS NULL
BEGIN
SELECT NULL AS DB_Name,*
INTO ##output
FROM authentication WHERE 1=0
END
INSERT INTO ##output
Select '''+ #DB_Name + ''' ,'+
--Enter query below
'* from authentication where username like ''%clair#indicater%'' and password = ''Rohan2410'''
-- print #Command
EXEC sp_executesql #Command
FETCH NEXT FROM database_cursor INTO #DB_Name
END
CLOSE database_cursor
DEALLOCATE database_cursor
SELECT * FROM ##output
DROP TABLE ##output
Basically, on the first cursor iteration we will create an empty temp table with the correct structure. Then we just insert into that temp table.
The script below shows an example query for data that have been converted from lower case, but it only changed the data on one column in the table.
Use MYF601T
Go
UPDATE ROAD_LINE
SET NAM = UPPER(NAM)
However, the following script that I'm trying to write is to convert all on all columns on all tables, but the result generated with errors.
Use MYF601T
Go
UPDATE INFORMATION_SCHEMA.TABLES
SET INFORMATION_SCHEMA.TABLES.TABLE_SCHEMA = UPPER(INFORMATION_SCHEMA.TABLES.TABLE_SCHEMA
How to do this for all tables and all columns inside?
If for whather reasons you want to convert your tables names to Upper case, you can:
use a cursor that will select the tables you want to rename
loop through the table list
rename it using sp_rename or update it
Note that you have to update the Select in the cursor to suit your needs (select column or table name you want, ...)
This will rename tables:
declare #TABLE_NAME sysname, #TABLE_SCHEMA sysname
declare #TABLE sysname, #newName sysname
declare table_cursor Cursor
For Select TABLE_NAME, TABLE_SCHEMA From INFORMATION_SCHEMA.TABLES Where TABLE_NAME like 'xyz%' -- and TABLE_SCHEMA like ...
open table_cursor
Fetch Next From table_cursor Into #TABLE_NAME, #TABLE_SCHEMA;
While ##FETCH_STATUS = 0
Begin
Set #TABLE = quotename(UPPER(#TABLE_SCHEMA)) + '.' + quotename(UPPER(#TABLE_NAME))
Set #newName = UPPER(#TABLE_NAME)
print 'rename ' + #TABLE + ' to ' + #newName
-- uncomment next like if you really want to rename them
--exec sp_rename #TABLE, #newName
Fetch Next From table_cursor Into #TABLE_NAME, #TABLE_SCHEMA;
End
Close table_cursor
Deallocate table_cursor
If you want to update all columns xyz in table zyx, you can use this:
declare #TABLE_NAME sysname, #TABLE_SCHEMA sysname, #COLUMN_NAME sysname
declare #TABLE sysname, #sql nvarchar(max)
declare table_cursor Cursor
For Select TABLE_NAME, TABLE_SCHEMA, COLUMN_NAME From INFORMATION_SCHEMA.COLUMNS
Where COLUMN_NAME like 'xxx' -- and data_type '' ... and TABLE_NAME like 'xyz%' ... and TABLE_SCHEMA like ...
open table_cursor
Fetch Next From table_cursor Into #TABLE_NAME, #TABLE_SCHEMA, #COLUMN_NAME;
While ##FETCH_STATUS = 0
Begin
Set #TABLE = quotename(#TABLE_SCHEMA) + '.' + quotename(#TABLE_NAME)
set #sql = 'Update ' + #TABLE + ' set ' + #COLUMN_NAME + ' = UPPER(' + #COLUMN_NAME + ')'
print #sql
-- uncomment next like if you really want to execute them
--exec sp_executesql #sql
Fetch Next From table_cursor Into #TABLE_NAME, #TABLE_SCHEMA, #COLUMN_NAME;
End
Close table_cursor
Deallocate table_cursor
Use a dynamic query to update all the column content to upper case.
Query
declare #query varchar(max)
select #query =
stuff
(
(
select ';update ' + table_name + ' ' +
'set ' + column_name + ' = upper(' + column_name + ')'
from information_schema.columns
where table_name = 'ROAD_LINE'
order by table_name,column_name
for xml path('')
)
, 1, 1, '')
execute(#query);
I'm trying to create a SQL Server script that applies some operations to all the tables in all the databases. I need to rename some tables if some conditions are respected, truncate the tables otherwise.
This is my script
EXEC sp_MSforeachdb
#command1 = '
IF not exists(select 1 where ''?'' in (''master'',''model'',''msdb'',''tempdb''))
EXEC [?].dbo.sp_MSforeachtable
#command1 = ''
IF(substring(&, 1, 3)=pv_ and right(&, 5) != _data and right(&, 4) != _BCK)
exec sp_RENAME & , &_BCK''
ELSE IF (right(&, 4) != _BCK)
TRUNCATE TABLE &
#replacechar = ''&'''
I got some errors but I'm new to SQL Server and I have not idea how to fix this script.
Any suggestions?
Many thanks
Here is a solution for start. It won't be quick, but it loops all tables of all databases on the server. Inside in the second cursor you can deceide what to do with the table.
(The query is not optimalized, just a quick solution)
DECLARE #DBName NVARCHAR(50)
DECLARE #TableName NVARCHAR(100)
DECLARE #DynamicSQL NVARCHAR(300)
DECLARE #DBCursor CURSOR
SET #DBCursor = CURSOR FOR
SELECT NAME FROM SYS.DATABASES
WHERE NAME NOT IN ('master','tempdb','model','msdb')
OPEN #DBCursor
FETCH NEXT FROM #DBCursor INTO #DBName
WHILE ##FETCH_STATUS = 0
BEGIN
CREATE TABLE #TempTableDatas
(
name varchar(100),
objectID int
)
SET #DynamicSQL = 'INSERT INTO #TempTableDatas
SELECT name, object_id FROM [' + #DBName + ']' + '.sys.Tables '
EXEC SP_EXECUTESQL #DynamicSQL
DECLARE #TableCursor CURSOR
SET #TableCursor = CURSOR FOR
SELECT name FROM #TempTableDatas
OPEN #TableCursor
FETCH NEXT FROM #TableCursor INTO #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #TableName, #DBName
FETCH NEXT FROM #TableCursor INTO #TableName
END
CLOSE #TableCursor
DEALLOCATE #TableCursor
DROP TABLE #TempTableDatas
FETCH NEXT FROM #DBCursor INTO #DBName
END
CLOSE #DBCursor
DEALLOCATE #DBCursor