How can I use sys.sp_MSforeachtable with different schema? - sql-server

I use SQL Server 2008 R2 and I want work with Change Data Capture.
I want run this command for my all Tables
EXEC sys.sp_cdc_enable_table
#source_schema = N'dbo',
#source_name = N'TestTable',
#role_name = NULL
I write this SQL statement .
Declare #Command NVarchar(Max)
Set #Command = '
EXEC sys.sp_cdc_enable_table
#source_schema = N''dbo'',
#source_name = N''?'',
#role_name = NULL
'
Exec sys.sp_MSforeachtable #Command
But I use several Schema in my database ?
How can I use sys.sp_MSforeachtable with different schema ?

you mean something like this :
exec sp_MSforeachtable
'select SUBSTRING(''?'', 0,
charindex(''.'', ''?'')),
SUBSTRING(''?'', charindex(''.'', ''?'') + 1, len(''?''))'
Please don't use cursor, and instead of sysview, you could have information_schema.tables

I think it would be easier to work with sys views for that kind of needs
declare #schemaName nvarchar(max);
declare #tableName nvarchar(max);
declare curs CURSOR FOR
select TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
where table_type = 'BASE TABLE'
OPEN curs
FETCH curs into #schemaName, #tableName
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC sys.sp_cdc_enable_table #source_schema = #schemaName, #source_name = #tableName, #role_name = null
FETCH curs into #schemaName, #tableName;
END
CLOSE curs
DEALLOCATE curs

Related

How to Backup and delete SQL Server database if the database created date is more than 3 months

How to Backup and delete SQL Server database if the database created date is more than 3 months
Be careful using something like this, this script could get you in to trouble. Notice I am only selecting the #tsql parameter, I commented out the EXEC so you can see what would be executing first.
/* Create a cursor to iterate through the databases you want to backup and delete */
DECLARE #tsql nvarchar(max)
DECLARE #dbname varchar(500)
DECLARE MyCursor CURSOR STATIC FORWARD_ONLY
FOR
SELECT [name]
FROM sys.databases
WHERE create_date < DATEADD (M, -3, GETDATE())
AND [name] NOT IN ('master', 'model', 'msdb', 'tempdb')
OPEN MyCursor
WHILE (1=1)
BEGIN
DECLARE
#Date varchar(20) = GETDATE()
FETCH NEXT FROM MyCursor INTO #dbname
IF ##FETCH_STATUS <> 0 BREAK
SET #tsql = 'BACKUP DATABASE [' + #dbname + '] TO DISK = N''S:\Backups\' + #dbname + ' ' + #Date + '.bak'' WITH NOFORMAT, NOINIT, SKIP, NOREWIND, NOUNLOAD, COMPRESSION, STATS = 10'
SELECT #tsql;
-- EXEC sp_executesql #tsql
SET #tsql = 'ALTER DATABASE [' + #dbname + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [' + #dbname + ']'
SELECT #tsql
-- EXEC sp_executesql #tsql
END
CLOSE MyCursor;
DEALLOCATE MyCursor;
GO

sql cursor insert result into a table

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.

transactional replication using script

I am able to configure transactional replication using SSMS and it works properly. But i want to configure it using script so that i use it from my c#/vb application.
Is there any way to do that?
If you complete all the step of transactional replication using SSMS then it's not complicated to do with the script.
Just carefully observe that when you configure distribution, publication and subscription SSMS gives you the option to generate script in every step.
You can use that generated script.
But only difference is when you add articles to publication. You can use the following code to add article
declare #name nvarchar(50)
declare curname cursor for
select name from sysobjects where type = 'U'
open curname
fetch next from curname into #name
while ##FETCH_STATUS = 0
begin
if exists(select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_TYPE = 'PRIMARY KEY' AND TABLE_NAME = #name AND TABLE_SCHEMA = 'dbo')
begin
exec sp_addarticle
#publication = N'publication_name', #article = #name, #source_owner = N'dbo',
#source_object = #name, #type = N'logbased', #description = null, #creation_script = null,
#pre_creation_cmd = N'drop', #schema_option = 0x000000000803509F,
#identityrangemanagementoption = N'manual', #destination_table = #name,
#destination_owner = N'dbo', #vertical_partition = N''
end
fetch next from curname into #name
end
close curname
deallocate curname
Or, you can see https://hasibarnab.wordpress.com/category/sql-server/replication/
DECLARE #returncode int
EXEC #returncode = xp_cmdshell 'dtexec /f "C:\thePackage.dtsx"'
Check out sp_addpublication, sp_addarticle, and sp_addsubscription in BOL.

Run operations on all the tables in all the databases

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

Can I apply an update statement to multiple databases at the same time?

Say I want to run the following:
update users set age = 10
on databases:
db1, db2, db3
All on the same server, I want to loop through and perform the same action.
Currently I am doing this manually using management studio via the dropdown.
Hoping there is a better way.
You could probably do it with dynamic SQL. Something like so:
create table #dbs (db_name sysname not null)
insert into #dbs values ('db1'),('db2'),('db3')
declare curs cursor for
select db_name from #dbs
declare #db sysname, #sql nvarchar(max)
open curs
while(1=1)
begin
fetch next from curs into #db
if (##fetch_status <> 0)
break
set #sql = 'update ' + quotename(#db) + '.dbo.users set age = 10'
exec(#sql)
end
close curs
deallocate curs
drop table #dbs
Not sure about doing it 'dynamically', i.e. a FOR-EACH style loop on all the databases in a server, but this should work:
USE db1
update users set age = 10
GO
USE db2
update users set age = 10
GO
USE db3
update users set age = 10
Designate a server as a central management server and then add the other servers to the server group. Then you can run the update on all databases within the group. http://msdn.microsoft.com/en-us/library/bb934126.aspx
use [WWAUTHxxx__] -- a db containing active databases.
set nocount on
declare #Catalog as nvarchar(32)
declare #LibraryName as varchar(255)
declare #dbtable as varchar(50)
declare #retval as nvarchar(50)
declare #sSQL as nvarchar(max)
declare #parmdef as nvarchar(500)
declare #retvalout as nvarchar(50)
Declare Library_Cursor Cursor for
select top(1000) xCatalog, xLibraryName
from Active_DBs
order by xcatalog
Open Library_Cursor;
Fetch Next from Library_Cursor into #Catalog, #LibraryName
while ##Fetch_status = 0
begin
set #dbTable = #Catalog + '.dbo.las_circperiods'
set #ParmDef = N'#retvalOUT int OUTPUT';
set #sSQL = N'Select #retvalout = count(*) from ' + #dbtable
+ ' where xlastcircdate is null'
exec sp_executesql #ssql,#parmdef,#retvalout=#retval output
if #retval > 0 -- check/print Sql and then activate.
-- I like checking to see the potentially affected databases.
begin
print #Catalog + ',' + #LibraryName + ',' + #retval
set #ssql = N'update ' + #dbTable
+ ' set xlastcircdate = '''' '
+ ' where xlastcircdate is null'
-- print #ssql -- View what you might will do
exec sp_executesql #ssql -- Do it.
end
Fetch Next from Library_Cursor into #Catalog, #LibraryName
end;
close Library_cursor
Deallocate Library_cursor

Resources