Not displaying select results from dynamic SQL within Cursor - sql-server

I'm currently learning SQL and trying to think of exercises for myself and I can't seem to make this one work even though it seems simple:
I'm trying to run a cursor through all the filtered tables within my db so that then I could pass that table name to a variable which will be used within a DynamicSQL inside the cursor. The end result should be all values from every column that has the column 'empid' in them.
However, the message returns as "Commands completed successfully" but I get to see no results despite my select statement.
I'm trying to run something like this:
declare #tablename nvarchar(200);
declare #empid int;
declare #sql nvarchar(200) = N'select * from ' + #tablename + N' where empid = ' +#empid;
declare tablecursor cursor for select table_name from information_schema.tables where col_length(table_name, 'empid') is not null;
open tablecursor;
fetch next from tablecursor into #tablename;
while ##fetch_status = 0
begin
execute sp_executesql #sql, 825
fetch next from tablecursor into #tablename;
end
close tablecursor;
deallocate tablecursor;
I've been searching everywhere for answers to make this work but can't find anything. I've tried putting into a stored procedure and then executing it from there but that didn't work either.
Help would be highly appreciated.

DECLARE #SQL Should be outside but assigning the Variable inside the while loop
SET #SQL = N'SELECT * FROM ' + #tableName
Should be in while loop.
The other thing is to increase the length of #SQL Variable.

Thank you kindly for the help. After I listened to your advice I've encountered more errors but at least for these I was able to find answers online. What I also learnt is that you can't have your sql string in quotes when you execute it as that will make SSMS treat #SQL as an actual string and not a variable. I've managed to get it working and my code now looks something like this:
create proc cdr #empid nvarchar(5) as
declare #tablename nvarchar(200);
declare tablecursor cursor for select table_name from information_schema.tables where col_length(table_name, 'empid') is not null;
open tablecursor;
fetch next from tablecursor into #tablename;
declare #sql nvarchar(max)
while ##fetch_status = 0
begin
set #sql = N'select * from ' + #tablename + N' where empid = ' + #empid;
execute sp_executesql #sql
fetch next from tablecursor into #tablename;
end
close tablecursor;
deallocate tablecursor;

Related

How iteration names of tables and delete records from them?

I am trying to create a procedure in which I create a variable -> #table_name and assign a select, that gets a list of tables names from sys.table.
Then I need to insert the #table_name to line with delete and go into each table from the list and delete records in them.
I will be grateful for help.
create procedure Test
as
declare #table_name = (select [name]
from sys.tables
where [name] like ('%x1') or [name] like ('%x2'))
-- how I can do the iteration???
delete [#table_name]
where id in (select id
from [#table_name]
where column_2 like ('%.%'))
I believe you need to use a cursor to loop through the selected table names and then construct and execute dynamic SQL. Something like:
declare #name sysname
declare #sql nvarchar(1000)
declare table_cursor cursor for
select name
from sys.tables
where name like '%x1' or name like '%x2'
open table_cursor
fetch next from table_cursor into #name
while ##fetch_status = 0
begin
set #sql = 'delete from ' + quotename(#name) + ' where column_2 like ''%.%'''
exec (#sql)
fetch next from table_cursor into #name
end
close table_cursor
deallocate table_cursor
I simplified the delete statement, but you may need to make additional changes to suit your specific needs. Note that because the '%.%' literal is itself contained withing another literal, the quotes are doubled up.

update statement value in multi table at once

I have over 100 tables in SQL Server 2000 with the same column name in each table. Now I want to update a value in 100 tables at once using a SQL update statement.
How do I do that? I try to google and stackoverflow but not really help.
Thanks so much
Create a cursor for all table in your database and using dynamic query to execute.
This script will be help you do this.
--USE [Your DB]
--GO
DECLARE #tableName VARCHAR(100)
DECLARE #sqlQuery VARCHAR(MAX)
DECLARE curTable CURSOR FOR SELECT name FROM sys.objects WHERE type_desc = 'USER_TABLE' AND name NOT IN ('sysdiagrams')
OPEN curTable
FETCH NEXT FROM curTable INTO #tableName
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #sqlQuery = 'UPDATE ' + #tableName + 'SET [YourCol1] = [YourVal1], [YourCol2] = [YourVal2] ...'
PRINT #sqlQuery
EXECUTE sp_executesql #sqlQuery
FETCH NEXT FROM curTable INTO #tableName
END
CLOSE curTable
DEALLOCATE curTable

Query number of records across all databases

I have multiple databases in my SQL Server. All databases are the same in structure but have different data. These databases are used to store sensor data so each sensor has it's own seperate DB in the SQL Server.
I want a query to Select the Database name and number of records in a specific table of each DB.
I tried with a cursor. I get error saying the name {query} is not a valid identifier. My Cursor is as follows:
Declare #dbname Varchar (50), #sql Varchar(1000)
Declare db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name LIKE 'EP505-%' -- All sensors of EP505
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #dbname
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql= 'SELECT Count(*) FROM [' + #dbname + '].dbo.TimeLine'
EXEC #sql
FETCH NEXT FROM db_cursor INTO #dbname
END
CLOSE db_cursor
DEALLOCATE db_cursor
In the output I require the db name and the number of records for the TimeLine table.
What's the best way to achieve what I am trying.
Use parentheses when executing a SQL query string like so:
EXEC (#sql). Without parentheses, SQL Server will interpret #sql as a stored procedure or user-defined function.
your attempt looks quite good so far.
Please try adding a fetch next below the exec-line and try putting the #SQL variable after the exec brackets. That worked in my SQL Server environment.
hope this helps
br
Patrik
You can use sp_executeSQL to execute your dynamic query instead of exec statement which will help you to solve your issue
Here is the modified version
Declare #dbname Varchar (50), #sql nVarchar(1000)
Declare db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name LIKE 'kodyaz' -- All sensors of EP505
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #dbname
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql= N'SELECT Count(*) FROM [' + #dbname + '].dbo.Kontaktpersonen'
exec sp_executesql #sql
FETCH NEXT FROM db_cursor INTO #dbname
END
CLOSE db_cursor
DEALLOCATE db_cursor
I change #sql data type to nvarchar() and use
exec sp_executesql #sql

Dynamic SQL parameter error, Incorrect syntax near '#myparametername'

I'm building a fun stored procedure that will use dynamic SQL, sp_executesql with parameters, to allow some alter statements for a column in all database tables if the column name exists ( As you can see I used a cursor for loop all the tables on DB)
I built a test but the parameter doesn't work, I get the next error on each alter table statement that runs
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '#parTablename'.
The next is the code
SET NOCOUNT ON;
GO
DECLARE #tablename varchar(100);
DECLARE #alteredColumn varchar(100)='[mycolumn] [datetimeoffset](0) NOT NULL;';
DECLARE #column varchar(100)='mycolumn';
DECLARE #parDefinition nvarchar(500) = N'#parTablename nvarchar(100)';
DECLARE #sqlCommand nvarchar(1000)= N'ALTER TABLE #parTablename ALTER COLUMN '+#alteredColumn;
DECLARE ALTERCURSOR CURSOR LOCAL FAST_FORWARD FOR
SELECT name AS tablename
FROM sys.Tables
OPEN ALTERCURSOR;
FETCH NEXT FROM ALTERCURSOR INTO #tablename
WHILE ##FETCH_STATUS = 0
BEGIN
--print #tablename
IF EXISTS(SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #tablename AND COLUMN_NAME = #column)
BEGIN
EXECUTE sp_executesql #sqlCommand, #parDefinition,#parTablename = #tablename
END
FETCH NEXT FROM ALTERCURSOR INTO #tablename
END
CLOSE ALTERCURSOR;
DEALLOCATE ALTERCURSOR;
SET NOCOUNT OFF;
GO
SOLUTION
Apparently is not possible to send a table name as a parameter, instead of that I used the #SeanLange option for degub with a little modification
SET #sqlCommand =Replace(#sqlCommand, '#parTablename',QUOTENAME(#tablename))
EXECUTE sp_executesql #sqlCommand
You can't stick a parameter in the middle of your dynamic sql like this. You need to use PRINT instead of EXECUTE to debug this. I wouldn't use a cursor for this myself but if you go that path you will have to do something like this before the EXECUTE statement.
Set #sqlCommand = Replace(sqlCommand, '#parTablename', #parTablename)

SQL Server 2008 Management Console: Automatically write results to a script and execute it

I would like to write a script which produces various statements out of a database.
Something like :
select 'DROP TABLE ['+ name + ']' from sys.objects where type = 'T' ;
I would like to automatically collect all output of such statements in a new file, and then I would like to execute this file. Is this possible ?
Important: The output should of course be without headers and without any other error/success, messages and so on.
In the optimal case, all necessary options for this should be set in the script itself, other than setting them in the user interface.
First, you create you dynamic script, something like...
DECLARE #sql NVARCHAR(MAX)
SELECT #sql =
COALESCE(#sql + CHAR(13), '') +
'DROP TABLE ['+ name + ']'
FROM sys.objects
WHERE [type] = 'T'
Execute that...
EXEC(#sql)
Then print that out to Messages-window...
PRINT #sql
And finally go to Messages-window, right-click it, select "Save results as...", Save as type > all files, and write your file name like myfile.sql
EDIT
I would never, EVER execute something like this automatically and without transaction. I'd rather save a script from Messages-window, open it, review it and then execute.
Are you wanting something like this?
If you only want to print the script use osql and a script something like this
DECLARE #schema VARCHAR(255)
DECLARE #table VARCHAR(255)
DECLARE PrintOutputCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT [TABLE_SCHEMA], [TABLE_NAME]
FROM INFORMATION_SCHEMA.TABLES
OPEN PrintOutputCursor
FETCH NEXT FROM PrintOutputCursor INTO #schema, #table
WHILE ##FETCH_STATUS = 0 BEGIN
PRINT 'DROP TABLE ['+ #schema + '].[' + #table + '];'
FETCH NEXT FROM PrintOutputCursor INTO #schema, #table
END
CLOSE PrintOutputCursor
DEALLOCATE PrintOutputCursor
If you want to execute the script using osql use this script (NOT RECOMMENDED)
DECLARE #schema VARCHAR(255)
DECLARE #table VARCHAR(255)
DECLARE #exec VARCHAR(4000)
DECLARE PrintOutputCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT [TABLE_SCHEMA], [TABLE_NAME]
FROM INFORMATION_SCHEMA.TABLES
OPEN PrintOutputCursor
FETCH NEXT FROM PrintOutputCursor INTO #schema, #table
WHILE ##FETCH_STATUS = 0 BEGIN
SET #exec = 'DROP TABLE ['+ #schema + '].[' + #table + '];'
-- Uncomment the following to execute the dynamic statement
-- EXEC (#exec)
FETCH NEXT FROM PrintOutputCursor INTO #schema, #table
END
CLOSE PrintOutputCursor
DEALLOCATE PrintOutputCursor

Resources