Iterate through all tables - sql

I'm looking for a way to iterate through all tables in a database.
I've come up with this so far:
DECLARE #TableName VARCHAR(MAX)
DECLARE MyCursor CURSOR
FOR
SELECT
DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_CATALOG ='MyDB'
AND TABLE_SCHEMA=N'dbo'
OPEN MyCursor
FETCH NEXT FROM MyCursor INTO #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT *
FROM #TableName
FETCH NEXT FROM MyCursor INTO #TableName
END
CLOSE MyCursor
DEALLOCATE MyCursor
I get an error message in the While statement The #TableName tablevariable must be declared (translated from German).
I know there should be a variable of the type TABLE at FROM #TableName, but I haven't found how to do that, just how to declare new tables which I don't want.

You can't SELECT * FROM #TableName
you will need to use Dynamic SQL
declare #sql nvarchar(max)
SELECT #sql = 'SELECT * FROM ' + QUOTENAME(#TableName)
exec sp_executesql #sql

In order to execute select on all your tables, you have to use dynamic SQL, as mentioned in other answer. Additionally, you don't need cursor at all! :)
Try this:
declare #sql varchar(max) = '';
select #sql = #sql + 'select * from ' + TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME + ' '
from information_schema.tables
exec(#sql)

Related

Update specific column in all tables base on specific value

I'm trying to update all table based on my value. This is a script Task in my SSIS package.
But I get the error:
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.
Code looks like this:
DECLARE #Column_name varchar(MAX)
DECLARE #Column_Datatype varchar(max)
SET #COLUMN_NAME='site_id'
SET #COLUMN_DATATYPE='varchar(10)'
------------------------------------------------Code---------------------------------------------------
GO
--Declare Variables
DECLARE #TableName VARCHAR(100)
DECLARE #TableSchema VARCHAR(100)
DECLARE #COLUMN_NAME VARCHAR(50)
DECLARE #COLUMN_NAME_UPDATE VARCHAR(50)
SET #COLUMN_NAME_UPDATE = ?
SET #COLUMN_NAME='site_id'
DECLARE #COLUMN_DATATYPE VARCHAR(50)
SET #COLUMN_DATATYPE='varchar(max)'
--Declare Cursor
DECLARE CUR CURSOR FOR
SELECT TABLE_SCHEMA,
TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
--OPEN CURSOR
OPEN CUR
--Fetch First Row
FETCH NEXT FROM CUR INTO #TableSchema,#TableName
--Loop
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #SQL NVARCHAR(MAX)
SET #SQL= ( SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME=#TableName AND COLUMN_NAME=#COLUMN_NAME
and Table_Schema=#TableSchema)
BEGIN
SET #SQL='UPDATE '+ #TableSchema+'.'+ '[' + #TableName + ']' + ' SET '+#COLUMN_NAME + '='
+ '''' + #COLUMN_NAME_UPDATE + '''' + 'WHERE site_id IS NULL '
PRINT #SQL
EXEC ( #SQL)
END
FETCH NEXT FROM CUR INTO #TableSchema,#TableName
END
--Close and Deallocate Cursor
CLOSE CUR
DEALLOCATE CUR
I use a variable like input.
What's wrong?

Create an ms sql query to get data from tables belonging to different schemas

I have a table named 'tbl_user' and this table exists under many schemas for example :
schema1.tbl_user
schema2.tbl_user
and so on. I would like to union all the data in these tables and get a single result and I cannot use any programming language because the environment I need to run it doesn't allow for it. Is there a way to accomplish this on sql server 2008 using stored procedures?
Edit : There are over a thousand schemas and schemas can be added and deleted as time goes.
using cursor, create the query dynamic and execute at when completed.
You can add additional filter if you want to filter out the schema.
DECLARE #NAME VARCHAR(100)
DECLARE #SQL NVARCHAR(300)
DECLARE #TABLE_NAME NVARCHAR(300)='userMaster'
DECLARE CUR CURSOR FOR
SELECT S.name
from sys.schemas s
inner join sys.sysusers u
on u.uid = s.principal_id
order by s.name
OPEN CUR
FETCH NEXT FROM CUR INTO #NAME
WHILE ##FETCH_STATUS = 0
BEGIN
IF (EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA =#NAME
AND TABLE_NAME =#TABLE_NAME))
BEGIN
IF(LEN(#SQL)>0)
begin
SET #SQL =#SQL+' UNION ALL SELECT * FROM ['+#NAME+'].['+#TABLE_NAME+']'
end
ELSE
begin
SET #SQL ='SELECT * FROM ['+#NAME+'].['+#TABLE_NAME+']'
end
--PRINT #SQL
END
FETCH NEXT FROM CUR INTO #NAME
END
CLOSE CUR
DEALLOCATE CUR
PRINT #SQL
exec(#SQL)
Try this and remember Tables should have the same structure.
SELECT *
FROM schema1.tbl_user
UNION
SELECT *
FROM schema2.tbl_user
And for large number of schemas you can use the following stored procedure. This will generate the UNION query dynamically and you can add the conditions to filter out the schema and table names.
DECLARE #table_name NVARCHAR(100)
DECLARE #schema_name NVARCHAR(100)
DECLARE #gettable CURSOR
DECLARE #query NVARCHAR(100)
SET #query=''
SET #gettable = CURSOR FOR
SELECT name,
schema_name(schema_id)
FROM sys.tables
OPEN #gettable
FETCH NEXT
FROM #gettable INTO #table_name, #schema_name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #query = #query + 'SELECT * FROM ' + #schema_name + '.'+ #table_name + ' UNION ';
FETCH NEXT
FROM #gettable INTO #table_name, #schema_name
END
CLOSE #gettable
DEALLOCATE #gettable
print #query;

SQL query to delete all tables and their data from a specific schema

I need to write a SQL query to delete all tables and their data from a specific schema.
For example in my database I have tables with schema dws6 and I want a script in SQL that will delete all the tables within the schema dws6.
I have tried below script and its working perfectly
DECLARE #SQL NVARCHAR(MAX);
DECLARE db_cursor CURSOR FOR
SELECT 'Drop Table ' + Table_Schema + '.' + Table_Name + ';'
FROM Information_Schema.Tables
WHERE Table_Type = 'BASE TABLE'
AND Table_Schema = 'dws6'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #SQL
WHILE ##FETCH_STATUS = 0
BEGIN
--PRINT #SQL
EXECUTE sp_executesql #SQL
FETCH NEXT FROM db_cursor INTO #SQL
END
CLOSE db_cursor
DEALLOCATE db_cursor;
This Query will generate all the DROP TABLE statements for you and PRINT the SQL statments
DECLARE #Sql VARCHAR(MAX)
SELECT #Sql =
COALESCE(#Sql, '') + 'DROP TABLE [DBO1].' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dws6'
PRINT #Sql

SQL -Query to find specific column in all the tables of the database but having no null values

I am not an SQL Expertise. I need to search for the column which is present in all the tables of the database but which does not has null values stored for that specific record.
Below is the query that fetches me all the tables that has my column name:
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE column_name LIKE 'classPK'
Try this...
declare #q nvarchar(1000);
declare cur_Select cursor for
select 'select * from ['+tab.name+'] where ['+col.name+'] is not null'
from sys.tables tab
join sys.columns col
on tab.object_id = col.object_id
where col.name like 'name'
open cur_Select
fetch next from cur_Select into #q
while ##FETCH_STATUS = 0
begin
exec sp_executesql #q
fetch next from cur_Select into #q
end
close cur_Select
deallocate cur_Select
Try with this statement:
DECLARE #TABLE_NAME NVARCHAR(MAX);
DECLARE #COLUMN_NAME NVARCHAR(MAX);
DECLARE #crs CURSOR;
DECLARE #query NVARCHAR(MAX);
set #crs = CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE column_name LIKE 'CD_CIC_PROD%'
BEGIN TRY
OPEN #crs
END TRY
BEGIN CATCH
END CATCH
FETCH NEXT FROM #crs INTO
#TABLE_NAME, #COLUMN_NAME
WHILE (##FETCH_STATUS = 0)
BEGIN
set #query = 'SELECT * FROM ['+#TABLE_NAME+'] WHERE ['+#COLUMN_NAME+'] IS NOT NULL'
EXEC sp_executesql #query
FETCH NEXT FROM #crs INTO
#TABLE_NAME, #COLUMN_NAME
END

INSERT INTO command doesn't work

I have one outer cursor and one inner cursor also have two tables to work with. Now with the outer cursor i'm making new columns in the table 1 and naming them by the values from the table two, and that works just fine. Problem is with the inner cursor witch i used to insert the values into those new columns from one specific column from another table. This seams not to work, but what confusing me is that i do not get any error messages. Now i hope you understand what i'm trying to do, here is the code so comment for more description about the problem :
DECLARE #rbr_param nvarchar(255)
DECLARE #vrednost nvarchar(255)
DECLARE #cName nvarchar(255)
DECLARE #sql nvarchar (255)
DECLARE curs CURSOR FOR SELECT DISTINCT rbr_param FROM dbo.parametri_pomocna ORDER BY rbr_param
OPEN curs
FETCH NEXT FROM curs
INTO #rbr_param
WHILE ##FETCH_STATUS = 0
BEGIN
SET #cName = 'P_'+#rbr_param+'_P'
EXEC('ALTER TABLE dbo.Parametri ADD ' + #cName + ' nvarchar(255)')
DECLARE vrd CURSOR FOR SELECT DISTINCT vrednost FROM dbo.parametri_pomocna
OPEN vrd
FETCH NEXT FROM vrd
INTO #vrednost
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = 'INSERT INTO dbo.Parametri'+(#cName)+ ' SELECT vrednost FROM dbo.parametri_pomocna WHERE vrednost = '+#vrednost+ ' AND rbr_param = '+#rbr_param
if exists (select * from INFORMATION_SCHEMA.COLUMNS where table_name = 'dbo.Parametri' and column_name = '#cName')
begin
exec(#sql)
end
FETCH NEXT FROM vrd
INTO #vrednost
END --end vrd
CLOSE vrd
DEALLOCATE vrd
FETCH NEXT FROM curs
INTO #rbr_param
END
CLOSE curs
DEALLOCATE curs
You have two problems here:
if exists ( select * from INFORMATION_SCHEMA.COLUMNS
where table_name = 'dbo.Parametri'
and column_name = '#cName'
)
(1) This view will never have table_name = schema name and table name.
(2) You have enclosed your variable name in single quotes for some reason.
For both of these reasons, your IF condition will never return true.
Try:
IF EXISTS
(
SELECT 1 FROM sys.columns
WHERE [object_id] = OBJECT_ID('dbo.Parametri')
AND name = #cName
)
(And here is why I prefer catalog views over INFORMATION_SCHEMA.)
Also this double-nested cursor thing seems quite inefficient and a lot more code than necessary to achieve what I think you're trying to do. How about something like this instead:
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + N'ALTER TABLE dbo.Parametri ADD '
+ QUOTENAME('P_' + rbr_param + '_P') + ' NVARCHAR(255);'
FROM dbo.parametri_pomocna GROUP BY rbr_param;
EXEC sp_executesql #sql;
SET #sql = N'';
SELECT #sql = #sql + N'INSERT dbo.Parametri('+QUOTENAME('P_' + rbr_param + '_P')+ ')
SELECT vrednost
FROM dbo.parametri_pomocna WHERE rbr_param = ''' + rbr_param + '''
GROUP BY vrednost;'
FROM dbo.parametri_pomocna
GROUP BY rbr_param;
EXEC sp_executesql #sql;