I am trying to change a stored procedure in our SQL environment which is used to create backup jobs remotely. Below is the procedure
/****** Object: StoredProcedure [dbo].[CreateBackupJobGroupBFull] Script Date: 8/06/2016 3:18:25 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[CreateBackupJobGroupAFull]
(#servername nvarchar(100))
AS
declare #commandstr nvarchar(max)
DECLARE #SQL nvarchar(4000)
DECLARE #TableExists bit
DECLARE #recp nvarchar(100)
DECLARE #error_msg varchar(300)
declare #groupAfull nvarchar(150)
declare #schedulestr nvarchar(150)
DECLARE #pripathstr VARCHAR(1256)
DECLARE #secpathstr VARCHAR(1256)
declare #defaultscheduleStart varchar(30)
declare #gstr varchar(5)
declare #g varchar(1)
set #groupAfull = 'DBABackupJobGroupA_Full'
set #recp = '**************'
set #defaultscheduleStart = '230000'
set #gstr = '_GA_F'
set #g = 'A'
SET #SQL = 'SELECT #TableExists = CASE WHEN TableExists = 0 THEN 0 ELSE 1 END
FROM OPENQUERY(' + QUOTENAME(#servername)
+ ', ''SELECT TableExists = COUNT(*)
from msdb.dbo.sysjobs
WHERE name = '''' + #groupAfull + '''''');';
begin try
EXECUTE sp_executesql #SQL, N'#TableExists BIT OUTPUT', #TableExists OUT;
END TRY
BEGIN CATCH
print 'error message is:'
print error_message()
set #error_msg='Error occurred when executing CreatBackupJob against server ' + #ServerName + '. Failed to check control table locally. The error message is: ' + error_message()
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Internal mail',
#recipients = #recp,
#body = #error_msg ,
#subject = 'Error occurred on reporting server' ;
END CATCH
IF (#TableExists = 0 )
BEGIN
--add new job for the instance
set #sql = 'if not exists (select * from [' + #ServerName + '].msdb.dbo.sysjobs where name = ''' + #groupAfull + ''')
BEGIN
EXEC [' + #ServerName + '].msdb.dbo.sp_add_job
#job_name = ''' + #groupAfull + ''',
#enabled = 1,
#description = N''DBA backup job. DO NOT REMOVE. V1.5 (2015-06-16)'',
#owner_login_name = N''sa''
EXEC [' + #ServerName + '].msdb.dbo.sp_add_jobserver
#job_name = ''' + #groupAfull + ''',
#server_name = ''(local)''
end
'
begin try
EXEC sp_executeSQL #sql
END TRY
BEGIN CATCH
print 'error message is:'
print error_message()
set #error_msg='Error occurred when executing CreatBackupJob against server ' + #ServerName + '. Failed to create new job'+ #groupAfull +'. The error message is: ' + error_message()
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Internal mail',
#recipients = #recp,
#body = #error_msg ,
#subject = 'Error occurred on reporting server' ;
END CATCH
SET #pripathstr = (SELECT Top 1 [PrimDestinationfull] FROM [SQLADMIN].[dbo].[BackupDestination])
SET #secpathstr = (SELECT Top 1 [SecDestinationfull] FROM [SQLADMIN].[dbo].[BackupDestination])
--add job step 1 'test'
set #commandstr = '
DECLARE #dbname VARCHAR(150) -- database name
DECLARE #pripath VARCHAR(1256) -- path for backup files
DECLARE #secpath VARCHAR(1256) -- path for backup files
DECLARE #path VARCHAR(1256) -- path for backup files
DECLARE #fileName VARCHAR(1256) -- filename for backup
DECLARE #fileDate VARCHAR(40) -- used for file name
DECLARE #DBGROUP varchar(1)
DECLARE #filecount int
DECLARE #lastbackuptime datetime
SET #DBGROUP = ''''' + #g + '''''
IF not EXISTS (SELECT [name] FROM msdb.sys.tables WHERE [name] = ''''DBBackupControlTbl'''' )
begin
raiserror(''''Control table not found!'''', 20, -1) with log
return
end
else
if (select count(*) from msdb.dbo.DBBackupControlTbl where BackupGroup = #DBGROUP) > 0
-- specify database backup directory
SET #pripath = ''''' + #pripathstr + '''''
SET #secpath = ''''' + #secpathstr + '''''
if object_id(''''tempdb.dbo.#fileExist'''') is not null
drop table #fileExist
create table #fileExist (
fileExists int,
fileIsDir int,
parentDirExists int
)
insert into #fileExist
exec xp_fileexist #pripath
if object_id(''''tempdb.dbo.#fileExist2'''') is not null
drop table #fileExist2
create table #fileExist2 (
fileExists int,
fileIsDir int,
parentDirExists int
)
insert into #fileExist2
exec xp_fileexist #secpath
if (select count(*) from #fileExist where fileIsDir = 1) > 0
begin
set #path = #pripath
end
ELSE
begin
if (select count(*) from #fileExist2 where fileIsDir = 1) > 0
begin
set #path = #secpath
end
ELSE
begin
raiserror(''''None of the backup directory can be accessed at the moment!'''', 20, -1) with log
return
end
end
set #filecount = 999
while #filecount >= 15
begin
IF OBJECT_ID(''''tempdb..#DirectoryTree'''') IS NOT NULL
DROP TABLE #DirectoryTree;
CREATE TABLE #DirectoryTree (
id int IDENTITY(1,1)
,subdirectory nvarchar(512)
,depth int
,isfile bit);
INSERT #DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree #path,1,1;
select #filecount = COUNT(*) FROM #DirectoryTree
WHERE isfile = 1 AND RIGHT(subdirectory,4) = ''''.sts''''
if #filecount >= 15
begin
print ''''Wait for status file to be cleared.''''
waitfor delay ''''00:00:10''''
end
else
begin
print ''''Backing up now.''''
DECLARE #statusfile AS VARCHAR(150)
DECLARE #cmd AS VARCHAR(150)
-- specify filename format
SELECT #fileDate = replace(replace(CONVERT(VARCHAR(40),GETDATE(),120), '''':'''', ''''-'''' ), '''' '''', ''''T'''')
set #statusfile = #path + replace(##SERVERNAME, ''''\'''', ''''-'''') + ''''_'''' + #fileDate + '''''+ #gstr + ''''' + ''''.STS''''
set #cmd = ''''echo '''' + #filedate + '''' > '''' + #statusfile
EXECUTE Master.dbo.xp_CmdShell #Cmd
DECLARE db_cursor CURSOR FOR
select databasename from msdb.dbo.DBBackupControlTbl where BackupGroup = #DBGROUP
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #dbname
WHILE ##FETCH_STATUS = 0
BEGIN
SET #fileName = #path + replace(##SERVERNAME, ''''\'''', ''''-'''') + ''''_'''' + #dbname + ''''_'''' + #fileDate + '''''+ #gstr + ''''' + ''''.BAK''''
BACKUP DATABASE #dbname TO DISK = #fileName
FETCH NEXT FROM db_cursor INTO #dbname
END
CLOSE db_cursor
DEALLOCATE db_cursor
set #cmd = ''''del '''' + #statusfile
EXECUTE Master.dbo.xp_CmdShell #Cmd
end
continue
end
'
print #commandstr
set #sql = 'if not exists (select * from [' + #ServerName + '].msdb.dbo.sysjobsteps where step_name = ''' + #groupAfull + ''')
BEGIN
EXEC [' + #ServerName + '].msdb.dbo.sp_add_jobstep
#job_name = ''' + #groupAfull + ''',
#step_name = ''' + #groupAfull + ''',
#subsystem = N''TSQL'',
#command = N''' + #commandstr + ''',
#retry_attempts = 3,
#retry_interval = 1,
#on_success_action = 1 ,
#on_fail_action= 2;
end
'
begin try
EXEC sp_executeSQL #sql
END TRY
BEGIN CATCH
print 'error message is:'
print error_message()
set #error_msg='Error occurred when executing CreatBackupJob against server ' + #ServerName + '. Failed to create new job step '+ #groupAfull +'. The error message is: ' + error_message()
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Internal mail',
#recipients = #recp,
#body = #error_msg ,
#subject = 'Error occurred on reporting server' ;
END CATCH
--add the schedule
set #schedulestr = #groupAfull + '_Schedule'
set #sql = 'if not exists (select * from [' + #ServerName + '].msdb.dbo.sysschedules where name = ''' + #schedulestr + ''')
BEGIN
EXEC [' + #ServerName + '].msdb.dbo.sp_add_schedule
#schedule_name = ''' + #schedulestr + ''',
#enabled=1,
#freq_type=4,
#freq_interval=1,
#freq_subday_type=1,
#freq_subday_interval=0,
#freq_relative_interval=0,
#freq_recurrence_factor=1,
#active_start_date=20140819,
#active_end_date=99991231,
#active_start_time= '+ #defaultscheduleStart +',
#active_end_time=235959
end
'
--print #sql
begin try
EXEC sp_executeSQL #sql
END TRY
BEGIN CATCH
print 'error message is:'
print error_message()
set #error_msg='Error occurred when executing CreatBackupJob against server ' + #ServerName + '. Failed to create new job schedule '+ #groupAfull +'. The error message is: ' + error_message()
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Internal mail',
#recipients = #recp,
#body = #error_msg ,
#subject = 'Error occurred on reporting server' ;
END CATCH
--attach the schedule
set #sql = 'EXEC [' + #ServerName + '].msdb.dbo.sp_attach_schedule
#job_name = ''' + #groupAfull + ''',
#schedule_name = ''' + #schedulestr + '''
'
begin try
EXEC sp_executeSQL #sql
END TRY
BEGIN CATCH
print 'error message is:'
print error_message()
set #error_msg='Error occurred when executing CreatBackupJob against server ' + #ServerName + '. Failed to attach the schedule to the job '+ #groupAfull +'. The error message is: ' + error_message()
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Internal mail',
#recipients = #recp,
#body = #error_msg ,
#subject = 'Error occurred on reporting server' ;
END CATCH
end
GO
The job created is created with 3 retries, so if backup fails it retires and then backs up all the database again irrespective where it failed. I am trying to change the procedure so that when the job fails it runs backup for databases which have failed. I have written below code to replace where it backups up database.
*#lastbackuptime is declared
BEGIN
SET #lastbackuptime = (select max(backup_finish_date) from msdb.dbo.backupset where database_name=#dbname and type=''''D'''')
if (Select datediff(hour,#lastbackuptime,getdate()))> 18
Begin
SET #fileName = #path + replace(##SERVERNAME, ''''\'''', ''''-'''') + ''''_'''' + #dbname + ''''_'''' + #fileDate + '''''+ #gstr + ''''' + ''''.BAK''''
BACKUP DATABASE #dbname TO DISK = #fileName
End
else
Begin
Print ''''Backup exists for database ''''
End
FETCH NEXT FROM db_cursor INTO #dbname
END
When I make this changes from job step , query parses fine and job runs fine. But when i put this in this procedure and try to create jobs remotely it fails with syntax error. As it is dynamic sql it does not provide me any clue where is the syntax error.
Would be great if someone can spot it.
Regards,
Sid
Questions of "Dynamic SQL not working" type come up often and sometimes (as in your case) can be very hard to answer, as we cannot execute the code you have supplied.
So this answer describes the method of debugging dynamic SQL.
Add a PRINT statement to print your dynamic SQL string just before it gets executed. When using PRINT command long strings can be truncated, so you need to use workarounds (How to print VARCHAR(MAX) using Print Statement? provides a few solutions).
Once you get your complete string printed check it for syntax errors and/or just run it. You can check code for syntax error by pasting it into a new query window and running "Parse" (Ctrl+F5).
Once the error in dynamic SQL is identified you need to find the place in your dynamic SQL generator code that produced this error and fix it there.
Repeat this process until no errors left.
Related
I wrote this query for searching a string in whole database . Earlier it was working properly now it doesn't fetch full result at all . I don't get what is wrong with this query . Please help
QUERY
/*
- Search through tables to find specific text
- Written by Luis Chiriff (with help from SQL Server Central)
- luis.chiriff#gmail.com # 24/11/2008 # 11:54
*/
-- Variable Declaration
Declare #StringToFind VARCHAR(200), #Schema sysname, #Table sysname, #FullTable int, #NewMinID
int, #NewMaxID int,
#SQLCommand VARCHAR(8000), #BaseSQLCommand varchar(8000), #Where VARCHAR(8000), #CountCheck
varchar(8000) , #FieldTypes varchar(8000),
#cursor VARCHAR(8000), #columnName sysname, #SCn int, #SCm int
Declare #TableList table (Id int identity(1,1) not null, tablename varchar(250))
Declare #SQLCmds table (id int identity(1,1) not null, sqlcmd varchar(8000))
Declare #DataFoundInTables table (id int identity(1,1) not null, sqlcmd varchar(8000))
-- Settings
SET #StringToFind = 'abcdef'
SET NOCOUNT ON
SET #StringToFind = '%'+#StringToFind+'%'
-- Gathering Info
if ((select count(*) from sysobjects where name = 'tempcount') > 0)
drop table tempcount
create table tempcount (rowsfound int)
insert into tempcount select 0
-- This section here is to accomodate the user defined datatypes, if they have
-- a SQL Collation then they are assumed to have text in them.
SET #FieldTypes = ''
select #FieldTypes = #FieldTypes + '''' + rtrim(ltrim(name))+''',' from systypes where collation
is not null or xtype = 36
select #FieldTypes = left(#FieldTypes,(len(#FieldTypes)-1))
insert into #TableList (tablename)
select name from sysobjects
where xtype = 'U' and name not like 'dtproperties'
order by name
-- Start Processing Table List
select #NewMinID = min(id), #NewMaxID = max(id) from #TableList
while(#NewMinID <= #NewMaxID)
Begin
SELECT #Table = tablename, #Schema='dbo', #Where = '' from #TableList where id = #NewMinID
SET #SQLCommand = 'SELECT * FROM ' + #Table + ' WHERE'
-- removed ' + #Schema + '.
SET #cursor = 'DECLARE col_cursor CURSOR FOR SELECT COLUMN_NAME
FROM [' + DB_NAME() + '].INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = ''' + #Schema + '''
AND TABLE_NAME = ''' + #Table + '''
AND DATA_TYPE IN ('+#FieldTypes+')'
--Original Check, however the above implements user defined data types --AND DATA_TYPE IN
(''char'',''nchar'',''ntext'',''nvarchar'',''text'',''varchar'')'
EXEC (#cursor)
SET #FullTable = 0
DELETE FROM #SQLCmds
OPEN col_cursor
FETCH NEXT FROM col_cursor INTO #columnName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #Where = #Where + ' [' + #columnName + '] LIKE ''' + #StringToFind + ''''
SET #Where = #Where + ' OR'
--PRINT #Table + '|'+ cast(len(isnull(#Where,''))+len(isnull(#SQLCommand,'')) as varchar(10))+'|'+#Where
if (len(isnull(#Where,''))+len(isnull(#SQLCommand,'')) > 3600)
Begin
SELECT #Where = substring(#Where,1,len(#Where)-3)
insert into #SQLCmds (sqlcmd) select #Where
SET #Where = ''
End
FETCH NEXT FROM col_cursor INTO #columnName
END
CLOSE col_cursor
DEALLOCATE col_cursor
if (#Where <> '')
Begin
SELECT #Where = substring(#Where,1,len(#Where)-3)
insert into #SQLCmds (sqlcmd)
select #Where --select #Table,count(*) from #SQLCmds
End
SET #BaseSQLCommand = #SQLCommand
select #SCn = min(id), #SCm = max(id) from #SQLCmds
while(#SCn <= #SCm)
Begin
select #Where = sqlcmd from #SQLCmds where ID = #SCn
if (#Where <> '')
Begin
SET #SQLCommand = #BaseSQLCommand + #Where
SELECT #CountCheck = 'update tempcount set rowsfound = (select count(*) '+ substring(#SQLCommand,10,len(#SQLCommand)) + ')'
EXEC (#CountCheck)
if ((select rowsfound from tempcount) > 0)
Begin
PRINT '--- ['+cast(#NewMinID as varchar(15))+'/'+cast(#NewMaxID as varchar(15))+'] '+#Table + ' ----------------------------------[FOUND!]'
--PRINT '--- [FOUND USING:] ' +#SQLCommand
insert into #DataFoundInTables (sqlcmd) select #SQLCommand
EXEC (#SQLCommand)
update tempcount set rowsfound = 0
End
else
Begin
PRINT '--- ['+cast(#NewMinID as varchar(15))+'/'+cast(#NewMaxID as varchar(15))+'] '+#Table
End
End
SET #SCn = #SCn + 1
End
set #NewMinID = #NewMinID + 1
end
if ((select count(*) from sysobjects where name = 'tempcount') > 0)
drop table tempcount
/*
This will now return all the sql commands you need to use
*/
select #NewMinID = min(id), #NewMaxID = max(id) from #DataFoundInTables
if (#NewMaxID > 0)
Begin
PRINT ' '
PRINT ' '
PRINT '-----------------------------------------'
PRINT '----------- TABLES WITH DATA ------------'
PRINT '-----------------------------------------'
PRINT ' '
PRINT 'We found ' + cast(#NewMaxID as varchar(10)) + ' table(s) with the string '+#StringToFind
PRINT ' '
while(#NewMinID <= #NewMaxID)
Begin
select #SQLCommand = sqlcmd from #DataFoundInTables where ID = #NewMinID
PRINT #SQLCommand
SET #NewMinID = #NewMinID + 1
End
PRINT ' '
PRINT '-----------------------------------------'
End
This query was working fine one month ago but now it doesn't fetch the results . Can anyone tell me what is wrong in this query .
43/5000
First of all I apologize for my bad english...
I am trying to write the insert procedures of all tables with a single procedure. But I have a problem like this.
DECLARE #jsondata varchar(MAX)
Set #jsondata='[{"RecordId":1,"CreatedUser":0,"CreatedDate":"2020-03-26T14:49:21.210","UpdatedDate":"2020-03-26T14:57:33.420","UpdatedUser":0,"Status":true,"IsDeleted":false,"Name":"Oyun Konsolları","Icon":"videogame_asset","Description":"Oyun Konsolları","Order":1}]';
DECLARE #cn nvarchar(50)
DECLARE #dt nvarchar(50)
DECLARE #ml nvarchar(50)
DECLARE #inserttext varchar(MAX)
DECLARE #selecttext varchar(MAX)
DECLARE #jsoncol varchar(MAX)
DECLARE #tablename varchar(50)
SET #tablename = 'Categories'
SET #inserttext = ' INSERT INTO '+#tablename+' ( ';
SET #selecttext = ' SELECT ';
SET #jsoncol = ') WITH (';
DECLARE #schema nvarchar(max) = N''
DECLARE MY_CURSOR CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT
c.name 'Column Name',
t.Name 'Data type',
c.max_length 'Max Length'
FROM
sys.columns c
INNER JOIN
sys.types t ON c.user_type_id = t.user_type_id
WHERE
c.object_id = OBJECT_ID(#tablename)
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO #cn,#dt,#ml
WHILE ##FETCH_STATUS = 0
BEGIN
IF(#cn NOT IN('CreatedUser','CreatedDate','UpdatedDate','UpdatedUser','Status','IsDeleted','RecordId','Status','IsDeleted'))
BEGIN
--Do something with Id here
SET #inserttext = #inserttext + '['+#cn + '], ';
SET #selecttext = #selecttext + '['+ #cn + '], ';
IF(#dt = 'varchar' OR #dt='nvarchar' )
BEGIN
SET #jsoncol = #jsoncol + '['+#cn + '] ' + #dt + ' (' +#ml + '), '
END
ELSE
BEGIN
SET #jsoncol = #jsoncol + '['+#cn + '] ' + #dt +', '
END
END
FETCH NEXT FROM MY_CURSOR INTO #cn,#dt,#ml
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
SET #jsoncol = LEFT(#jsoncol, LEN(#jsoncol) - 1)
SET #inserttext = LEFT(#inserttext, LEN(#inserttext) - 1)
SET #selecttext = LEFT(#selecttext, LEN(#selecttext) - 1)
SET #inserttext =#inserttext + ' )';
SET #jsoncol = #jsoncol + ' )';
EXEC( #inserttext + ' '+ #selecttext + ' ' +' FROM OPENJSON('+#jsondata+ #jsoncol);
Error i get after running :
Msg 103, Level 15, State 4, Line 1 The identifier that
starts with
'{"RecordId":1,"CreatedUser":0,"CreatedDate":"2020-03-26T14:49:21.210","UpdatedDate":"2020-03-26T14:57:33.420","UpdatedUser":0,"S'
is too long. Maximum length is 128.
Completion time: 2020-09-25T10:42:41.2474477+03:00
29/5000
Is it possible ?
in short, is it possible to insert into tables from json as dynamic exec
declare #sql nvarchar(max) = #inserttext + ' '+ #selecttext + ' ' +' FROM OPENJSON(#thejsondata'+ #jsoncol;
exec sp_executesql #stmt=#sql, #params=N'#thejsondata nvarchar(max)', #thejsondata = #jsondata;
I am declaring a dynamic cursor due to a nesting of the stored procedure based on a parent-child relationship of the data that can go multiple levels and vary daily when processed. The stored procedure works for the parent call, however the process of this procedure for child data causes a message stating that the "Cursor is not open." This message occurs on the Fetch which is immediately after checking to be sure the cursor is open.
DECLARE #OutCur CURSOR;
DECLARE #curName as NVARCHAR(MAX);
...
SET #curName = LEFT(replace(replace(CONVERT (time, GETDATE()),':',''),'.',''),8);
SET #sqlCommand = 'SELECT a.myfields FROM mytable a;
SET #sqlCommand = 'SET #cursor' + #curName + ' = CURSOR LOCAL FAST_FORWARD FOR ' + #sqlCommand + ' OPEN #cursor' + #curName + ';'
SET #curName = '#cursor' + #curName + ' cursor output';
EXEC sys.sp_executesql #sqlCommand,#curName,#OutCur output
IF CURSOR_STATUS('global','#OutCur')=-1
OPEN #OutCur;
FETCH NEXT FROM #OutCur INTO #name,#type
Thanks in advance for the input.
if you uncomment close+deallocate - script works fine:
GO
DECLARE #OutCur CURSOR;
DECLARE #curName as NVARCHAR(MAX), #sqlCommand nvarchar(max), #name varchar(100), #type varchar(100)
declare #i int = 0
while #i < 5
begin
SET #curName = LEFT(replace(replace(CONVERT (time, GETDATE()),':',''),'.',''),8);
SET #sqlCommand = 'SELECT ''111'' as name, ''cc'' as type; '
SET #sqlCommand = 'SET #cursor' + #curName + ' = CURSOR LOCAL FAST_FORWARD FOR ' + #sqlCommand + ' OPEN #cursor' + #curName + ';'
SET #curName = '#cursor' + #curName + ' cursor output';
EXEC sys.sp_executesql #sqlCommand,#curName,#OutCur output
FETCH NEXT FROM #OutCur INTO #name,#type
select #name, #type
--close #OutCur
--deallocate #OutCur
set #i += 1
end
GO
I've written the below code to set filepath column in my table as 'F:\DataMigration\Wise\DELTA_20121008\Attachments\SR\SR_1.txt'
where SR_1 is file_name column
.txt is file_ext column from my table.
but after executing following procedure, I'm getting filepath column in table as
'F:\DataMigration\Wise\DELTA_20121008\Attachments\file_name.file_ext'
means It's treating column names as string, how i can make it as column so it will
use values in that column.
alter procedure [dbo].[WISEMissingAttachmentReportGenerator]
(
#tablename varchar(255), #pathonlocal nvarchar(255)
)
as
begin
--step 1
exec dbo.proc_alter_table #tablename
--step 2
EXEC ('update '+ #tablename +
' set filepath = '''+ #pathonlocal + ' file_name'+'.'+'file_ext''')
EXEC('Select * from '+#tablename)
end
exec [dbo].[WISEMissingAttachmentReportGenerator] [WISE.Non_VP_Service_Request_Attachments_File_Check_Analysis],
N'F:\DataMigration\Wise\DELTA_20121008\Attachments\SR\'
Try;
EXEC('UPDATE '+ #tablename +
' SET filepath = '''+ #pathonlocal + ''' + file_name + '''+'.'+''' + file_ext')
Equal as;
UPDATE [YourTable] SET filepath = 'YourPath' + file_name + '.' + file_ext
Try changing your statement to this:
EXEC ('update '+ #tablename +
' set filepath = '''+ #pathonlocal + ''' + file_name + ''.'' + file_ext')
declare #tblnm varchar(20) = 'test'
declare #upda varchar(20) = 'update '
declare #set varchar(25) = ' set'
declare #id varchar(25) = ' id'
declare #cmd varchar(1000)
set #cmd = #upda + #tblnm + #set + #id + '=7'
exec(#cmd)
SAMPLE SQL UPDATE QUERY - FOR BUILDING TABLENAME DYNAMICALLY
EXECUTED GUYS - THIS IS CALL JUGAAAAAAAAAD [NO NEED TO GET INTO ''' STUFF]
We have implemented log shipping as a database disaster recovery solution and want to know if there is a way I can use T-SQL to script all the logins, users, roles permissions etc to the master database on the secondary server so that the T-SQL can be sheduled to run as an SQL Job?
My aim is that in the event of a D/R situation we can simply restore the transaction logs for each database to the secondary server and not have to worry about orphaned users etc.
Thanks for you help!
There is a login copy script here designed to copy logins to another server for disaster recovery purposes:
http://www.sqlsoldier.com/wp/sqlserver/transferring-logins-to-a-database-mirror
Use master;
Go
If Exists (Select 1 From INFORMATION_SCHEMA.ROUTINES
Where ROUTINE_NAME = 'dba_CopyLogins'
And ROUTINE_SCHEMA = 'dbo')
Drop Procedure dbo.dba_CopyLogins
Go
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
Create Procedure dbo.dba_CopyLogins
#PartnerServer sysname,
#Debug bit = 0
As
Declare #MaxID int,
#CurrID int,
#SQL nvarchar(max),
#LoginName sysname,
#IsDisabled int,
#Type char(1),
#SID varbinary(85),
#SIDString nvarchar(100),
#PasswordHash varbinary(256),
#PasswordHashString nvarchar(300),
#RoleName sysname,
#Machine sysname,
#PermState nvarchar(60),
#PermName sysname,
#Class tinyint,
#MajorID int,
#ErrNumber int,
#ErrSeverity int,
#ErrState int,
#ErrProcedure sysname,
#ErrLine int,
#ErrMsg nvarchar(2048)
Declare #Logins Table (LoginID int identity(1, 1) not null primary key,
[Name] sysname not null,
[SID] varbinary(85) not null,
IsDisabled int not null,
[Type] char(1) not null,
PasswordHash varbinary(256) null)
Declare #Roles Table (RoleID int identity(1, 1) not null primary key,
RoleName sysname not null,
LoginName sysname not null)
Declare #Perms Table (PermID int identity(1, 1) not null primary key,
LoginName sysname not null,
PermState nvarchar(60) not null,
PermName sysname not null,
Class tinyint not null,
ClassDesc nvarchar(60) not null,
MajorID int not null,
SubLoginName sysname null,
SubEndPointName sysname null)
Set NoCount On;
If CharIndex('\', #PartnerServer) > 0
Begin
Set #Machine = LEFT(#PartnerServer, CharIndex('\', #PartnerServer) - 1);
End
Else
Begin
Set #Machine = #PartnerServer;
End
-- Get all Windows logins from principal server
Set #SQL = 'Select P.name, P.sid, P.is_disabled, P.type, L.password_hash' + CHAR(10) +
'From ' + QUOTENAME(#PartnerServer) + '.master.sys.server_principals P' + CHAR(10) +
'Left Join ' + QUOTENAME(#PartnerServer) + '.master.sys.sql_logins L On L.principal_id = P.principal_id' + CHAR(10) +
'Where P.type In (''U'', ''G'', ''S'')' + CHAR(10) +
'And P.name <> ''sa''' + CHAR(10) +
'And P.name Not Like ''##%''' + CHAR(10) +
'And CharIndex(''' + #Machine + '\'', P.name) = 0;';
Insert Into #Logins (Name, SID, IsDisabled, Type, PasswordHash)
Exec sp_executesql #SQL;
-- Get all roles from principal server
Set #SQL = 'Select RoleP.name, LoginP.name' + CHAR(10) +
'From ' + QUOTENAME(#PartnerServer) + '.master.sys.server_role_members RM' + CHAR(10) +
'Inner Join ' + QUOTENAME(#PartnerServer) + '.master.sys.server_principals RoleP' +
CHAR(10) + char(9) + 'On RoleP.principal_id = RM.role_principal_id' + CHAR(10) +
'Inner Join ' + QUOTENAME(#PartnerServer) + '.master.sys.server_principals LoginP' +
CHAR(10) + char(9) + 'On LoginP.principal_id = RM.member_principal_id' + CHAR(10) +
'Where LoginP.type In (''U'', ''G'', ''S'')' + CHAR(10) +
'And LoginP.name <> ''sa''' + CHAR(10) +
'And LoginP.name Not Like ''##%''' + CHAR(10) +
'And RoleP.type = ''R''' + CHAR(10) +
'And CharIndex(''' + #Machine + '\'', LoginP.name) = 0;';
Insert Into #Roles (RoleName, LoginName)
Exec sp_executesql #SQL;
-- Get all explicitly granted permissions
Set #SQL = 'Select P.name Collate database_default,' + CHAR(10) +
' SP.state_desc, SP.permission_name, SP.class, SP.class_desc, SP.major_id,' + CHAR(10) +
' SubP.name Collate database_default,' + CHAR(10) +
' SubEP.name Collate database_default' + CHAR(10) +
'From ' + QUOTENAME(#PartnerServer) + '.master.sys.server_principals P' + CHAR(10) +
'Inner Join ' + QUOTENAME(#PartnerServer) + '.master.sys.server_permissions SP' + CHAR(10) +
CHAR(9) + 'On SP.grantee_principal_id = P.principal_id' + CHAR(10) +
'Left Join ' + QUOTENAME(#PartnerServer) + '.master.sys.server_principals SubP' + CHAR(10) +
CHAR(9) + 'On SubP.principal_id = SP.major_id And SP.class = 101' + CHAR(10) +
'Left Join ' + QUOTENAME(#PartnerServer) + '.master.sys.endpoints SubEP' + CHAR(10) +
CHAR(9) + 'On SubEP.endpoint_id = SP.major_id And SP.class = 105' + CHAR(10) +
'Where P.type In (''U'', ''G'', ''S'')' + CHAR(10) +
'And P.name <> ''sa''' + CHAR(10) +
'And P.name Not Like ''##%''' + CHAR(10) +
'And CharIndex(''' + #Machine + '\'', P.name) = 0;'
Insert Into #Perms (LoginName, PermState, PermName, Class, ClassDesc, MajorID, SubLoginName, SubEndPointName)
Exec sp_executesql #SQL;
Select #MaxID = Max(LoginID), #CurrID = 1
From #Logins;
While #CurrID <= #MaxID
Begin
Select #LoginName = Name,
#IsDisabled = IsDisabled,
#Type = [Type],
#SID = [SID],
#PasswordHash = PasswordHash
From #Logins
Where LoginID = #CurrID;
If Not Exists (Select 1 From sys.server_principals
Where name = #LoginName)
Begin
Set #SQL = 'Create Login ' + quotename(#LoginName)
If #Type In ('U', 'G')
Begin
Set #SQL = #SQL + ' From Windows;'
End
Else
Begin
Set #PasswordHashString = '0x' +
Cast('' As XML).value('xs:hexBinary(sql:variable("#PasswordHash"))', 'nvarchar(300)');
Set #SQL = #SQL + ' With Password = ' + #PasswordHashString + ' HASHED, ';
Set #SIDString = '0x' +
Cast('' As XML).value('xs:hexBinary(sql:variable("#SID"))', 'nvarchar(100)');
Set #SQL = #SQL + 'SID = ' + #SIDString + ';';
End
If #Debug = 0
Begin
Begin Try
Exec sp_executesql #SQL;
End Try
Begin Catch
Set #ErrNumber = ERROR_NUMBER();
Set #ErrSeverity = ERROR_SEVERITY();
Set #ErrState = ERROR_STATE();
Set #ErrProcedure = ERROR_PROCEDURE();
Set #ErrLine = ERROR_LINE();
Set #ErrMsg = ERROR_MESSAGE();
RaisError(#ErrMsg, 1, 1);
End Catch
End
Else
Begin
Print #SQL;
End
If #IsDisabled = 1
Begin
Set #SQL = 'Alter Login ' + quotename(#LoginName) + ' Disable;'
If #Debug = 0
Begin
Begin Try
Exec sp_executesql #SQL;
End Try
Begin Catch
Set #ErrNumber = ERROR_NUMBER();
Set #ErrSeverity = ERROR_SEVERITY();
Set #ErrState = ERROR_STATE();
Set #ErrProcedure = ERROR_PROCEDURE();
Set #ErrLine = ERROR_LINE();
Set #ErrMsg = ERROR_MESSAGE();
RaisError(#ErrMsg, 1, 1);
End Catch
End
Else
Begin
Print #SQL;
End
End
End
Set #CurrID = #CurrID + 1;
End
Select #MaxID = Max(RoleID), #CurrID = 1
From #Roles;
While #CurrID <= #MaxID
Begin
Select #LoginName = LoginName,
#RoleName = RoleName
From #Roles
Where RoleID = #CurrID;
If Not Exists (Select 1 From sys.server_role_members RM
Inner Join sys.server_principals RoleP
On RoleP.principal_id = RM.role_principal_id
Inner Join sys.server_principals LoginP
On LoginP.principal_id = RM.member_principal_id
Where LoginP.type In ('U', 'G', 'S')
And RoleP.type = 'R'
And RoleP.name = #RoleName
And LoginP.name = #LoginName)
Begin
If #Debug = 0
Begin
Exec sp_addsrvrolemember #rolename = #RoleName,
#loginame = #LoginName;
End
Else
Begin
Print 'Exec sp_addsrvrolemember #rolename = ''' + #RoleName + ''',';
Print ' #loginame = ''' + #LoginName + ''';';
End
End
Set #CurrID = #CurrID + 1;
End
Select #MaxID = Max(PermID), #CurrID = 1
From #Perms;
While #CurrID <= #MaxID
Begin
Select #PermState = PermState,
#PermName = PermName,
#Class = Class,
#LoginName = LoginName,
#MajorID = MajorID,
#SQL = PermState + space(1) + PermName + SPACE(1) +
Case Class When 101 Then 'On Login::' + QUOTENAME(SubLoginName)
When 105 Then 'On ' + ClassDesc + '::' + QUOTENAME(SubEndPointName)
Else '' End +
' To ' + QUOTENAME(LoginName) + ';'
From #Perms
Where PermID = #CurrID;
If Not Exists (Select 1 From sys.server_principals P
Inner Join sys.server_permissions SP On SP.grantee_principal_id = P.principal_id
Where SP.state_desc = #PermState
And SP.permission_name = #PermName
And SP.class = #Class
And P.name = #LoginName
And SP.major_id = #MajorID)
Begin
If #Debug = 0
Begin
Begin Try
Exec sp_executesql #SQL;
End Try
Begin Catch
Set #ErrNumber = ERROR_NUMBER();
Set #ErrSeverity = ERROR_SEVERITY();
Set #ErrState = ERROR_STATE();
Set #ErrProcedure = ERROR_PROCEDURE();
Set #ErrLine = ERROR_LINE();
Set #ErrMsg = ERROR_MESSAGE();
RaisError(#ErrMsg, 1, 1);
End Catch
End
Else
Begin
Print #SQL;
End
End
Set #CurrID = #CurrID + 1;
End
Set NoCount Off;