I am trying to create a dynamic SQL query and perform insert operation. But for some reason, I am getting
error: Conversion failed when converting the varchar value '
Please can anyone help me in resolving this error. Getting error at values('#file_type_id'
Below is my SQL code:
DECLARE #file_name VARCHAR(100) = 'MyFile'
DECLARE #file_type_id INT = 1
DEclare #filing_id bigint = 57
DECLARE #created_at DATETIME = GETDATE()
DECLARE #created_by BIGINT = 2
DECLARE #is_confidential bit = 1
set #insertquery =
'
DECLARE #Document AS VARBINARY(MAX)
SELECT #Document = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET( BULK ''C:\SampleTestFiles\MyWordDoc.doc'', SINGLE_BLOB ) AS Doc
Insert ['+#databasename+'].['+#schemaname+'].['+#tablename+']
( [file_type_id], [file], [file_name], [filing_id], [created_at], [created_by], [is_confidential])
values ( '#file_type_id', #Document, #file_name, #filing_id , #created_at, #created_by, #is_confidential)
'
exec (#insertquery)
I suspect this is what you are after. Note that I have parametrised the variables, and safely quoted the values of your dynamic objects:
DECLARE #databasename sysname,
#schemaname sysname,
#tablename sysname;
DECLARE #file_name varchar(100) = 'MyFile',
#file_type_id int = 1,
#filing_id bigint = 57,
#created_at datetime = GETDATE(),
#created_by bigint = 2,
#is_confidential bit = 1,
#CRLF nchar(2) = NCHAR(13) + NCHAR(10),
#insertquery nvarchar(MAX);
SET #insertquery = N'DECLARE #Document AS VARBINARY(MAX);' + #CRLF +
N'SELECT #Document = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET( BULK ''C:\SampleTestFiles\MyWordDoc.doc'', SINGLE_BLOB ) AS Doc;' + #CRLF + #CRLF +
N'INSERT INTO ' + QUOTENAME(#databasename) + '.' + QUOTENAME(#schemaname) + N'.' + QUOTENAME(#tablename) + N' ( [file_type_id], [file], [file_name], [filing_id], [created_at], [created_by], [is_confidential])' + #CRLF +
N'VALUES (#file_type_id, #Document, #file_name, #filing_id , #created_at, #created_by, #is_confidential);';
--PRINT #insertquery; --Your best friend.
EXEC sp_executesql #insertquery, N'#file_name varchar(100),#file_type_id int,#filing_id bigint,#created_at datetime, #created_by bigint,#is_confidential bit', #file_name, #file_type_id, #filing_id, #created_at, #created_by, #is_confidential;
I can't test the above, however, if you get any errors I would suggest looking at your best friend. if, however, I use the declarations below...:
DECLARE #databasename sysname = N'MyDB',
#schemaname sysname = N'dbo',
#tablename sysname = N'MyTable';
I get this statement, which appears to be correct:
DECLARE #Document AS VARBINARY(MAX);
SELECT #Document = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET( BULK 'C:\SampleTestFiles\MyWordDoc.doc', SINGLE_BLOB ) AS Doc;
INSERT INTO [MyDB].[dbo].[MyTable] ( [file_type_id], [file], [file_name], [filing_id], [created_at], [created_by], [is_confidential])
VALUES (#file_type_id, #Document, #file_name, #filing_id , #created_at, #created_by, #is_confidential);
Edit: to address the comment from the OP "How do I put another variable for file path." the correct syntax of that would be to make use of the second parameter from QUOTENAME (note that this strongly assumes that #filepath can never have a length longer than 128 characters):
SET #insertquery = N'DECLARE #Document AS VARBINARY(MAX);' + #CRLF +
N'SELECT #Document = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET( BULK ' + QUOTENAME(#filepath,'''') + N', SINGLE_BLOB ) AS Doc;' + #CRLF + #CRLF +
N'INSERT INTO ' + QUOTENAME(#databasename) + '.' + QUOTENAME(#schemaname) + N'.' + QUOTENAME(#tablename) + N' ( [file_type_id], [file], [file_name], [filing_id], [created_at], [created_by], [is_confidential])' + #CRLF +
N'VALUES (#file_type_id, #Document, #file_name, #filing_id , #created_at, #created_by, #is_confidential);';
Related
I'm using an original script I found a long time ago to create a bulk import of many CSV files into an SQL database. With minor adjustments the script is working for me, but I can't get rid of the double quotes as FIELDQUOTE.
DECLARE #Path NVARCHAR(255) = 'D:\TEMP\'
DECLARE #RowTerminator NVARCHAR(5) = CHAR(13) + CHAR(10)
DECLARE #ColumnTerminator NVARCHAR(5) = CHAR(44)
DECLARE #FieldQuote NVARCHAR(5) = CHAR(34)
--DECLARE #FieldQuote NVARCHAR(5) = '"'
IF OBJECT_ID('[dbo].[Files_Temporary]', 'U') IS NOT NULL
DROP TABLE [dbo].[Files_Temporary];
CREATE TABLE [dbo].[Files_Temporary]
(
[ID] INT
, [FileName] NVARCHAR(255)
, [TableName] NVARCHAR(255)
);
INSERT INTO [dbo].[Files_Temporary] SELECT 1, 'MyFile.txt', 'MyfileA'
INSERT INTO [dbo].[Files_Temporary] SELECT 2, 'MyFile.txt', 'MyFileB'
DECLARE #Counter INT = 1
WHILE #Counter <= (SELECT COUNT(*) FROM [dbo].[Files_Temporary])
BEGIN
PRINT 'Counter is ''' + CONVERT(NVARCHAR(5), #Counter) + '''.'
DECLARE #FileName NVARCHAR(255)
DECLARE #TableName NVARCHAR(255)
DECLARE #Header NVARCHAR(MAX)
DECLARE #SQL_Header NVARCHAR(MAX)
DECLARE #CreateHeader NVARCHAR(MAX) = ''
DECLARE #SQL_CreateHeader NVARCHAR(MAX)
SELECT #FileName = [FileName], #TableName = [TableName] FROM [dbo].[Files_Temporary] WHERE [ID] = #Counter
IF OBJECT_ID('[dbo].[' + #TableName + ']', 'U') IS NULL
BEGIN
PRINT 'Creating new table with name ''' + #TableName + '''.'
IF OBJECT_ID('[dbo].[Header_Temporary]', 'U') IS NOT NULL
DROP TABLE [dbo].[Header_Temporary];
CREATE TABLE [dbo].[Header_Temporary]
(
[Header] NVARCHAR(MAX)
);
SET #SQL_Header = '
BULK INSERT [dbo].[Header_Temporary]
FROM ''' + #Path + #FileName + '''
WITH
(
FIRSTROW = 1,
LASTROW = 1,
MAXERRORS = 0,
FIELDTERMINATOR = ''' + #RowTerminator + ''',
ROWTERMINATOR = ''' + #RowTerminator + ''',
FIELDQUOTE = ''' + #FieldQuote + '''
)'
EXEC(#SQL_Header)
SET #Header = (SELECT TOP 1 [Header] FROM [dbo].[Header_Temporary])
PRINT 'Extracted header ''' + #Header + ''' for table ''' + #TableName + '''.'
WHILE CHARINDEX(#ColumnTerminator, #Header) > 0
BEGIN
SET #CreateHeader = #CreateHeader + '[' + LTRIM(RTRIM(SUBSTRING(#Header, 1, CHARINDEX(#ColumnTerminator, #Header) - 1))) + '] NVARCHAR(255), '
SET #Header = SUBSTRING(#Header, CHARINDEX(#ColumnTerminator, #Header) + 1, LEN(#Header))
END
SET #CreateHeader = #CreateHeader + '[' + #Header + '] NVARCHAR(255)'
SET #SQL_CreateHeader = 'CREATE TABLE [' + #TableName + '] (' + #CreateHeader + ')'
EXEC(#SQL_CreateHeader)
END
PRINT 'Inserting data from ''' + #FileName + ''' to ''' + #TableName + '''.'
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = '
BULK INSERT [dbo].[' + #TableName + ']
FROM ''' + #Path + #FileName + '''
WITH
(
FIRSTROW = 2,
MAXERRORS = 0,
FIELDTERMINATOR = ''' + #ColumnTerminator + ''',
ROWTERMINATOR = ''' + #RowTerminator + ''',
FIELDQUOTE = ''' + #FieldQuote + '''
)'
EXEC(#SQL)
SET #Counter = #Counter + 1
END;
IF OBJECT_ID('[dbo].[Files_Temporary]', 'U') IS NOT NULL
DROP TABLE [dbo].[Files_Temporary];
IF OBJECT_ID('[dbo].[Header_Temporary]', 'U') IS NOT NULL
DROP TABLE [dbo].[Header_Temporary];
I've declared a variable, but neither the of both give me the correct result. The import is succesfull, but fieldquote is not ignored.
DECLARE #FieldQuote NVARCHAR(5) = CHAR(34)
--DECLARE #FieldQuote NVARCHAR(5) = '"'
I'm using SSMS V18.10
Just add one more setting like below to take care of double quotes.
It will work starting from SQL Server 2017 onwards.
SQL
...
WITH (
FORMAT='CSV'
...
I know this sp returns Orphanded users :
EXEC sp_change_users_login #Action='Report'
I try to find Orphaned users in all databases on SQL Server but it's not returns true result.
DECLARE #name NVARCHAR(MAX),#sql NVARCHAR(MAX), #sql2 NVARCHAR(MAX);
DECLARE #dbname NVARCHAR(MAX);
DECLARE Crs CURSOR
FOR
SELECT name FROM sys.sysdatabases where dbid>4 and name not in(
SELECT DB_NAME(dr_state.database_id) as name
FROM (( sys.availability_groups AS ag JOIN sys.availability_replicas AS ar ON ag.group_id = ar.group_id )
JOIN sys.dm_hadr_availability_replica_states AS ar_state ON ar.replica_id = ar_state.replica_id)
JOIN sys.dm_hadr_database_replica_states dr_state on ag.group_id = dr_state.group_id
and dr_state.replica_id = ar_state.replica_id
where ar_state.role_desc='SECONDARY' AND ar_state.is_local=1
)
OPEN Crs
FETCH NEXT FROM Crs INTO #Name
/*WHILE ## FETCH_STATUS = 0 It means keep returning the cursor by moving to the next record until there are no records left to circulate in the cursor.*/
WHILE ##FETCH_STATUS =0
BEGIN
SELECT name FROM sys.sysdatabases where name=#name
select #dbname=name from sysdatabases where name=#name
use #dbname
EXEC sp_change_users_login #Action='Report'
FETCH NEXT FROM Crs INTO #Name
END
/*CLOSE ve DEALLOCATE commad closed Cursor*/
CLOSE Crs
DEALLOCATE Crs
my error:Msg 102, Level 15, State 1, Line 49
Incorrect syntax near '#dbname'.
If I assign the database name to the #dbname variable, the problem will be solved.
Thanks.
It seems, to me, that you just want to list all the Users, in your databases, that don't have a related LOGIN, excluding Loginless objects. As I mentioned sp_change_users_login is deprecated, so you shouldn't be using that, but you can get the information from the sys.database_principles and sys.server_principles objects. So for a single database you could do something like this:
SELECT db_name(),
dp.[name] AS UserName,
dp.[sid] AS UserSID
FROM sys.database_principals dp
WHERE dp.[type] IN ('U','S')
AND NOT EXISTS (SELECT 1
FROM sys.server_principals sp
WHERE sp.sid = dp.sid)
AND authentication_type > 0;
I'm going to (shamelessly) us my sp_foreachdatabase proc (A CURSOR free version of sp_msforeachdb) and then use the dynamic SQL to put all the data into a single temporary table, and SELECT that at the end. This gives something like this (I have included definition of my objects at the end of this answer):
DECLARE #CRLF nchar(2) = NCHAR(13) + NCHAR(10);
DECLARE #PreCommand nvarchar(MAX) = N'CREATE TABLE #Orphans (DBName sysname,' + #CRLF +
N' UserName sysname,' + #CRLF +
N' UserSID varbinary(85));';
DECLARE #Command nvarchar(MAX) = N'INSERT INTO #Orphans (DBName, UserName, UserSID)' + #CRLF +
N'SELECT db_name(),' + #CRLF +
N' dp.[name] AS UserName,' + #CRLF +
N' dp.[sid] AS UserSID' + #CRLF +
N'FROM sys.database_principals dp' + #CRLF +
N'WHERE dp.[type] IN (''U'',''S'')' + #CRLF +
N' AND NOT EXISTS (SELECT 1' + #CRLF +
N' FROM sys.server_principals sp' + #CRLF +
N' WHERE sp.sid = dp.sid)' + #CRLF +
N' AND authentication_type > 0;';
DECLARE #PostCommand nvarchar(MAX) = N'SELECT DBName, UserName, UserSID FROM #Orphans; DROP TABLE #Orphans;';
DECLARE #CommandRun nvarchar(MAX);
EXEC master.dbo.sp_foreachdatabase #Pre_Command = #PreCommand,
#Command = #Command,
#Post_Command = #PostCommand,
#Exit_On_Error = 0,
#Skip_System = 1,
#Auto_Use = 1,
#Command_Run = #CommandRun OUTPUT;
This puts all the orphaned users into temporary table, with their database's name, and then SELECTs them at the end.
Object definitions:
USE master;
GO
IF NOT EXISTS (SELECT 1 FROM sys.types WHERE [name] = N'objectlist')
CREATE TYPE dbo.objectlist AS table ([name] sysname);
GO
USE master;
GO
CREATE OR ALTER PROC sp_foreachdatabase #Command nvarchar(MAX),
#Delimit_Character nchar(1) = N'?', --Character to be replaced with a delimit identified version of the datbaase name I.e. [master]
#Quote_Character nchar(1) = N'&', --Character to be replaced with a single quoted (') version of the datbaase name I.e. 'master'
#Skip_System bit = 0, --Omits master, msdb, tempdb and model. Ignored if #Database_List has data.
#Skip_User bit = 0, --Omits all user databases. Ignored if #Database_List has data.
#Database_List dbo.objectlist READONLY, --If #Skip_System and #Skip_User equal 1, and this is empty, an error will be thrown
#Auto_Use bit = 0, --Automatically starts each command agaisnt a database with a USE
#Exit_On_Error bit = 1, --If an error is occurs against a single database, the command will still be run against the remainder. Otherwise everything is rolled back
--This does not effect the #Pre_Command and #Post_Command statements
#Pre_Command nvarchar(MAX) = NULL, --Command to run before #Command. Does not use Character Replacements. Run against master DB.
#Post_Command nvarchar(MAX) = NULL, --Command to run after #Command. Does not use Character Replacements. Run against master DB.
#Command_Run nvarchar(MAX) = NULL OUTPUT --Returns the generated and replaced command, for trouble shooting
AS BEGIN
--Do some checking of passed values first
--Check that #Skip_System, #Skip_User aren't both 0 or that #Database_List has some rows
IF (#Skip_System = 1 AND #Skip_User = 1 AND NOT EXISTS (SELECT 1 FROM #Database_List))
THROW 62401, N'System and User databases cannot be skipped if a Database List is not supplied.', 16;
IF #Delimit_Character IS NULL OR #Delimit_Character = ''
THROW 62402, N'#Delimit_Character cannot have a value of NULL or ''''.', 16;
IF #Quote_Character IS NULL OR #Quote_Character = ''
THROW 62403, N'#Quote_Character cannot have a value of NULL or ''''.', 16;
IF #Skip_User IS NULL
THROW 62404, N'#Skip_User cannot have a value of NULL.', 16;
IF #Skip_System IS NULL
THROW 62405, N'#Skip_System cannot have a value of NULL.', 16;
IF #Auto_Use IS NULL
PRINT N'#Auto_Use has a value of NULL. Behaviour will be as if the value is 0.';
DECLARE #CRLF nchar(2) = NCHAR(13) + NCHAR(10);
DECLARE #RC int;
--Add the Pre Command to the batch
SET #Command_Run = ISNULL(N'/* --- Pre Command Begin. --- */' + #CRLF + #CRLF + N'USE master;' + #CRLF + #CRLF + #Pre_Command + #CRLF + #CRLF + N'/* --- Pre Command End. --- */', N'');
--Get the databases we need to deal with
--As #Database_List might be empty and it's READONLY, and we're going to do the command in database_id order we need another variable.
DECLARE #DBs table (database_id int,
database_name sysname);
IF EXISTS (SELECT 1 FROM #Database_List)
INSERT INTO #DBs (database_id,database_name)
SELECT d.database_id,
d.[name]
FROM sys.databases d
JOIN #Database_List DL ON d.[name] = DL.[name];
ELSE
INSERT INTO #DBs (database_id,database_name)
SELECT d.database_id,
d.[name]
FROM sys.databases d
WHERE (d.database_id <= 4 AND #Skip_System = 0) OR (d.database_id > 4 AND #Skip_User = 0);
SET #Command_Run = #Command_Run + #CRLF + #CRLF +
N'/* --- Begin command for each database. --- */' + #CRLF + #CRLF +
CASE WHEN #Exit_On_Error = 0 THEN N'--Turning XACT_ABORT off due to #Exit_On_Error parameter' + #CRLF + #CRLF + N'SET XACT_ABORT OFF;' + #CRLF + N'DECLARE #Error nvarchar(4000);' ELSE N'SET XACT_ABORT ON;' END +
(SELECT #CRLF + #CRLF +
N'/* --- Running #Command against database ' + QUOTENAME(DB.database_name,'''') + N'. --- */' + #CRLF + #CRLF +
CASE WHEN #Auto_Use = 1 THEN N'USE ' + QUOTENAME(DB.database_name) + N';' + #CRLF + #CRLF ELSE N'' END +
N'BEGIN TRY' + #CRLF + #CRLF +
REPLACE(REPLACE(#Command, #Delimit_Character, QUOTENAME(DB.database_name)),#Quote_Character, 'N' + QUOTENAME(DB.database_name,'''')) + #CRLF + #CRLF +
'END TRY' + #CRLF +
N'BEGIN CATCH' + #CRLF +
CASE WHEN #Exit_On_Error = 0 THEN N' SET #Error = N''The following error occured during the batch, but has been skipped:'' + NCHAR(13) + NCHAR(10) + ' + #CRLF +
N' N''Msg '' + CONVERT(nvarchar(6),ERROR_NUMBER()) + '', Level '' + CONVERT(nvarchar(6),ERROR_SEVERITY()) + '', State '' + CONVERT(nvarchar(6),ERROR_STATE()) + '', Line '' + CONVERT(nvarchar(6),ERROR_LINE()) + NCHAR(13) + NCHAR(10) +' + #CRLF +
N' ERROR_MESSAGE();' + #CRLF +
N' PRINT #Error;' + #CRLF +
N' SET #RC = ERROR_NUMBER();'
ELSE N' THROW;'
END + #CRLF +
N'END CATCH;' + #CRLF +
N'/* --- Completed #Command against database ' + QUOTENAME(DB.database_name,'''') + N'. --- */'
FROM #DBs DB
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)') + #CRLF + #CRLF +
CASE WHEN #Exit_On_Error = 0 THEN N'--Turning XACT_ABORT back on due to #Exit_On_Error parameter' + #CRLF + #CRLF + N'SET XACT_ABORT ON;' ELSE N'' END;
SET #Command_Run = #Command_Run + ISNULL(#CRLF + #CRLF + N'/* --- Post Command Begin. --- */' + #CRLF + #CRLF + N'USE master;' + #CRLF + #CRLF + #Post_Command + #CRLF + #CRLF + N'/* --- Post Command End. --- */', N'');
EXEC sp_executesql #Command_Run, N'#RC int OUTPUT', #RC = #RC;
SET #RC = ISNULL(#RC, 0);
RETURN #RC;
END;
GO
I am trying to make the procedure where I can get the data from MS SQL. Here I am getting the error
Msg 245, Level 16, State 1, Procedure GET_FUNCTIONS, Line 15 [Batch Start Line 33]
Conversion failed when converting the varchar value ' and f.FUNCTION_ID in '' to data type int.
CREATE procedure [dbo].[GET_FUNCTIONS]
#Function_Id int,
#EntityId int,
#OrderBy varchar(10)
as
begin
declare #Sql nvarchar(max)
if(#Function_Id=0 AND #EntityId=0)
set #Sql = 'select
f.Function_Code,f.FUNCTION_ID,f.EntityId,be.ENTITY_SHORT_NAME,f.FUNCTION_NAME,
f.FUNCTION_DESC,f.CREATED_DATE,f.MODIFIED_DATE from FUNCTIONS f
inner join BusinessEntity be on f.EntityId=be.ID
WHERE f.ACTIVE=1 '
if(#Function_Id!=0)
set #Sql += ' and f.FUNCTION_ID in ''' + #Function_Id + ''''
if(#EntityId!=0)
set #Sql += ' and f.EntityId = cast('+convert(varchar(12) ,#EntityId)+') '
set #Sql += ' order by FUNCTION_ID '+ #OrderBy
print #Sql
end
GO
Thanks everyone for your answers. I have got the answer by my own.
I have removed if(#Function_Id=0 AND #EntityId=0) and changed the data type of #Function_Id and #EntityId to varchar(100), so solved all errors.
I'm, making a few guesses here, which I add some comments about, however, this should be what you are after. I firstly ensure that I parametrise the values, but also validate and quote the value of #OrderBy:
CREATE PROCEDURE [dbo].[GET_FUNCTIONS] #Function_Id int =NULL, --Instead of passing 0as "select all" use NULL
#EntityId int = NULL, --Instead of passing 0as "select all" use NULL
#OrderBy nvarchar(4) --guessing this is mean to be ASC or DESC?
AS
BEGIN
IF #OrderBy NOT IN (N'ASC','DESC')
--Error is not ASC or DESC
THROW 51473, N'#OrderBy can only have a value of ''ASC'' or ''DESC''.',16; --51473 was a random error number; you can use one that is appropriate for your environment.
DECLARE #SQL nvarchar(MAX),
#CRLF nchar(2) = NCHAR(13) + NCHAR(10);
SET #SQL = N'SELECT f.Function_Code,' + + #CRLF +
N' f.FUNCTION_ID,' + + #CRLF +
N' f.EntityId,' + + #CRLF +
N' be.ENTITY_SHORT_NAME,' + + #CRLF +
N' f.FUNCTION_NAME,' + + #CRLF +
N' f.FUNCTION_DESC,' + + #CRLF +
N' f.CREATED_DATE,' + + #CRLF +
N' f.MODIFIED_DATE' + + #CRLF +
N'FROM FUNCTIONS f' + + #CRLF +
N' INNER JOIN BusinessEntity be ON f.EntityId = be.ID' + + #CRLF +
N'WHERE f.ACTIVE = 1';
IF (#Function_Id IS NOT NULL)
SET #SQL = #SQL + #CRLF + N' AND f.FUNCTION_ID = #Function_Id'
IF (#EntityId IS NOT NULL)
SET #SQL = #SQL + #CRLF + N' AND f.EntityId = #EntityId'
SET #SQL = #SQL + #CRLF +
N'ORDER BY F.FUNCTION_ID ' + QUOTENAME(#OrderBy) + N';'
--PRINT #SQL; --Uncomment for debugging.
EXEC sp_executesql #SQL, N'#Function_Id int, #EntityId int', #Function_Id, #EntityId;
END;
GO
I use dynamic sql with parameters and have problem :)
In block of code it works, but when I call procedure I have error that I need to declare scalar variable #name_dummy
So:
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT
o.SCHEMA_N
,o.TABLE_N
,o.Condition
,o.TargetDB
,o.SourceDB
,STUFF((SELECT
', ' + c.name
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH (''))
, 1, 1, '')
FROM Table_A o
ORDER BY 1,
2
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = ( SELECT CAST(Wartosc AS VARCHAR) FROM Table_B WHERE Id = 3 )
IF #TOP < 40000
SET #TOP = 40000
WHILE ( 1 = 1 )
BEGIN
DECLARE #CHECK BIT = 0
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM '
+ #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
SELECT #sqlCMD , #CHECK
END
END
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
CLOSE KUR;
DEALLOCATE KUR
And when I execute this it's compiling and works ( returns values ) for example sql which I want to execute.
SELECT TOP 1 #check_exists = 1 FROM MSSF15_WarstwaPosrednia.KatalogZdarzen.MSSF_RaportZdarzenPLKB2CS2K WHERE StatusPrzetwarzania = 4 AND DataWpisu < DATEADD(MONTH, -3, #START_TIME)
Parameters work here ( #check_exists which is output and #START_TIME condition param ) , but when I execute this in procedure I'm getting error
Must declare the scalar variable "#START_TIME". 137
SP definition:
USE xxxx
/****** Object: StoredProcedure dbo.dummy Script Date: 06/09/2018 13:40:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE dbo.dummy
AS
BEGIN
/*
PRZENIESIENIE DANYCH
*/
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT o.SCHEMA_N,
o.TABLE_N,
o.Condition,
o.TargetDB,
o.SourceDB,
STUFF((
SELECT ', ' + c.NAME
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH('')
), 1, 1, '')
FROM dbo.Table_A o
ORDER BY 1,
2
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = (
SELECT CAST(Wartosc AS VARCHAR)
FROM dbo.Table_B
WHERE Id = 3
)
IF #TOP < 40000
SET #TOP = 40000
WHILE (1 = 1)
BEGIN
BEGIN TRY
BEGIN TRANSACTION T_TEST
DECLARE #CHECK BIT = 0
DECLARE #START_TIME_P DATE = GETDATE()
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
SELECT #CHECK,
#START_TIME_P,
#sqlCMD
EXEC sp_executesql #sqlCMD,
N'#check_exists bit OUTPUT, #START_TIME DATE',
#check_exists = #CHECK OUTPUT,
#START_TIME = #START_TIME_P;
IF OBJECT_ID('tempdb..#TMP_ID') IS NOT NULL
DROP TABLE #TMP_ID
CREATE TABLE #TMP_ID (Id INT)
EXEC (
'INSERT INTO #TMP_ID
SELECT TOP ' + #TOP + ' Id
FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
)
DECLARE #sqlCMD_Ins NVARCHAR(MAX)
SET #sqlCMD_Ins = 'INSERT INTO ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' '
SET #sqlCMD_Ins = #sqlCMD_Ins + 'SELECT ' + #COLUMN_LIST + ' FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Ins IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Ins)
DECLARE #sqlCMD_Del NVARCHAR(MAX)
SET #sqlCMD_Del = 'DELETE FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Del IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Del)
DROP TABLE #TMP_ID
COMMIT TRANSACTION T_TEST
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION T_TEST
PRINT 'Wycofanie zmian'
PRINT ERROR_MESSAGE() + ' ' + CAST(ERROR_NUMBER() AS VARCHAR(256))
END
END CATCH
IF #CHECK = 0
BREAK
END
EXEC ('SELECT ''' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' UNION ALL ' + 'SELECT ''' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N)
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
END
CLOSE KUR;
DEALLOCATE KUR;
DECLARE #END_TIME DATETIME = GETDATE()
SELECT 'Daty przetworzenia',
#START_TIME_P AS 'START',
#END_TIME AS 'END'
SELECT 'Czas (min)',
DATEDIFF(MINUTE, #START_TIME_P, #END_TIME)
END
Guys, maybe u have similar situation and can help.
Error msg
Wycofanie zmian
Must declare the scalar variable "#START_TIME". 137
Thanks
Instead of
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
try
declare #date_in DATE = GETDATE()
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #date_in;
I am searching a query which generate html table. I found this query, but I can not understand what is use of such so many single quote used here and
why all code create in variable. I am new in sql please help me.
BEGIN
SET NOCOUNT ON;
IF #orderBy IS NULL
BEGIN
SET #orderBy = ''
END
SET #orderBy = REPLACE(#orderBy, '''', '''''');
DECLARE #realQuery NVARCHAR(MAX) = ' //this is variable which take all query as string
DECLARE #headerRow nvarchar(MAX);
DECLARE #cols nvarchar(MAX);
SELECT * INTO #dynSql FROM (' + #query + ') sub; -- how this temp table create
SELECT #cols = COALESCE(#cols + '', '''''''', '', '''') + ''['' + name + ''] AS ''''td''''''
FROM tempdb.sys.columns
WHERE object_id = object_id(''tempdb..#dynSql'')
ORDER BY column_id;
SET #cols = ''SET #html = CAST(( SELECT '' + #cols + '' FROM #dynSql ' + #orderBy + ' FOR XML PATH(''''tr''''), ELEMENTS XSINIL) AS nvarchar(max))''
EXEC sys.sp_executesql #cols, N''#html nvarchar(MAX) OUTPUT'', #html=#html OUTPUT
--in coalesce why so many '''' used
SELECT #headerRow = COALESCE(#headerRow + '''', '''') + ''<th>'' + name + ''</th>''
FROM tempdb.sys.columns
WHERE object_id = object_id(''tempdb..#dynSql'')
ORDER BY column_id;
SET #headerRow = ''<tr>'' + #headerRow + ''</tr>'';
SET #html = ''<table border="1">'' + #headerRow + #html + ''</table>'';
';
EXEC sys.sp_executesql #realQuery
,N'#html nvarchar(MAX) OUTPUT'
,#html = #html OUTPUT
END
Above query is working fine, but I can't understand it.