I know you can do this easily using the GUI in SSMS. But,is there a way to include all the articles with TSQL instead of doing them one by one using sp_addarticle?
My initial idea is returning all the tables names(using a sys query) and then using a loop to feed them to sp_addarticle. I'm wondering if there's a smarter way for example a built-in variable that I can assign 'all' to it?
This is how I did it
USE [DatabaseName]
DECLARE #name sysname
DECLARE #getid CURSOR
SET #getid = CURSOR FOR
-- Select all tables name
SELECT [name]
FROM [DataBaseName].[sys].[tables]
WHERE is_ms_shipped=0
-- While loop
OPEN #getid
FETCH NEXT
FROM #getid INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
-- add article
exec sp_addarticle #publication = #publication
,#article = #name
,#source_object = #name
,#del_cmd = 'NONE'
FETCH NEXT
FROM #getid INTO #name
END
CLOSE #getid
DEALLOCATE #getid
Related
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.
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;
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
we have some database with a lot of views, functions and procedures.
We will update some of them. Therefore i´ve written this script.
My question is, is that a common way and is that the right way?
Any suggestion will be appreciated.
-- update procedures and functions
USE mydb
GO
DECLARE #ticker nvarchar(255)
DECLARE #definition nvarchar(max)
DECLARE #newdefinition nvarchar(max)
DECLARE crsVorgang SCROLL CURSOR FOR
SELECT ROUTINE_NAME,ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_CATALOG = 'mydb' and ROUTINE_DEFINITION like '%something%'
ORDER BY ROUTINE_NAME
OPEN crsVorgang
FETCH FIRST FROM crsVorgang INTO #ticker, #definition
WHILE (##FETCH_STATUS <> -1)
BEGIN
set #newdefinition = REPLACE(#definition,'sometext', 'newtext')
--print #newdefinition
update INFORMATION_SCHEMA.ROUTINES
set ROUTINE_DEFINITION = #newdefinition
where ROUTINE_NAME = #ticker
FETCH NEXT FROM crsVorgang INTO #ticker, #definition
END
CLOSE crsVorgang
DEALLOCATE crsVorgang
GO
The answer is, it is not possible with update INFORMATION_SCHEMA.ROUTINES, cause it is not allowed.
The right way (for me) to a reproduceable bulk update from lots of procedures and functions is now a drop and create, so i have modified my script to the following:
USE [mydb]
GO
DECLARE #ticker nvarchar(255)
DECLARE #definition nvarchar(max)
DECLARE #routinetype nvarchar(255)
DECLARE #newdefinition nvarchar(max)
DECLARE #dropdefinition nvarchar(max)
DECLARE crsVorgang SCROLL CURSOR FOR
SELECT ROUTINE_NAME,ROUTINE_DEFINITION, ROUTINE_TYPE FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_CATALOG = 'mydb' and ROUTINE_DEFINITION like '%something%'
ORDER BY ROUTINE_NAME
OPEN crsVorgang
FETCH FIRST FROM crsVorgang INTO #ticker, #definition, #routinetype
WHILE (##FETCH_STATUS <> -1)
BEGIN
set #dropdefinition = 'DROP '+ #routinetype +' [dbo].'+#ticker
set #newdefinition = REPLACE(#definition,'sometext', 'newtext')
exec (#dropdefinition)
exec (#newdefinition)
FETCH NEXT FROM crsVorgang INTO #ticker, #definition, #routinetype
END
CLOSE crsVorgang
DEALLOCATE crsVorgang
GO
thanks for your spent time
I have worked on SQL Server database. Now I have to work on a Sybase database (using a Squirrel client). This query is not working :
DECLARE #tableName VARCHAR(500);
DECLARE my_cursor CURSOR FOR
SELECT name
FROM sysobjects
WHERE type = 'U';
OPEN my_cursor;
FETCH NEXT FROM my_cursor INTO #tableName;
WHILE ##FETCH_STATUS = 0
BEGIN
//Do something here
FETCH NEXT FROM my_cursor;
END
CLOSE my_cursor;
DEALLOCATE CURSOR my_cursor;
It gives an error - Incorrect syntax near the keyword 'FROM'.
SQLState: ZZZZZ
ErrorCode: 156
Error occured in:
FETCH NEXT FROM my_cursor INTO #table_Name
Now this works fine in a SQL Server database (after I change the last line to DEALLOCATE my_cursor). Can anybody tell me where I am going wrong?
As Mitch points out the fetch syntax is:
fetch cursor_name [into fetch_target_list]
You also need to declare the cursor in a separate batch, this means you must put a "GO" after the declare statement. You will then find that your variable drops out of scope, so you'll need to move that so that it's after the "GO".
You also need to examine ##sqlstatus to see how successful the fetch was, rather than ##FETCH_STATUS which I think is MSSQL only.
DECLARE my_cursor CURSOR FOR
SELECT name
FROM sysobjects
WHERE type = 'U'
go
DECLARE #tableName VARCHAR(500)
set nocount on
OPEN my_cursor
FETCH my_cursor INTO #tableName
WHILE ##sqlstatus = 0
BEGIN
--Do something here
FETCH my_cursor INTO #tableName
print #tablename
END
CLOSE my_cursor
DEALLOCATE CURSOR my_cursor
And no semicolons needed at the end of lines in Sybase ASE.
DECLARE #tableName VARCHAR(500);
DECLARE my_cursor CURSOR FOR
SELECT name
FROM sysobjects
WHERE type = 'U';
OPEN my_cursor;
FETCH my_cursor INTO #tableName;
WHILE ##FETCH_STATUS = 0
BEGIN
//Do something here
FETCH my_cursor INTO #tableName;
END
CLOSE my_cursor;
DEALLOCATE CURSOR my_cursor;
Declare #tablename after the cursor.
First of all Squirrel supports go as a SQL batch separator. Go to menu item Session--> Session Properties---> 'SQL' Tab.
Scroll to bottom and set 'Statement Separator' as 'go' (quotes not needed) .
Then follow the previous answer . The DECLARE CUROSR can be the only SQL statement in a batch , hence you must insert go after it.
In the next batch re-declare any variables that were declared in earlier batch and will be referenced in second batch.
This should work. This is how I have been testing SQL code involving cursors for years.