Dynamic SQL - parametrized query - sql

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;

Related

Bulk import T-SQL ignoring double quote (")

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'
...

Search a string in whole mysql database

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 .

SQL Server Dynamic insert script JSON For

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;

Generate script with INSERT SELECT statements from T-SQL

I have two databases in SQL Server 2014 Express, since a few days ago I am unifying both databases in such a way that there is only one left.
When I have this new database I must pass it to Azure (I don't have any experience using this technology), however, I am doing tests on my local server, so far I have created the whole scheme but I must fill out all the tables to perform tests with my application.
There are 313 tables of which many have more than 200,000 records, my question is, what is the best way to populate the database?
Because at this moment I want to test my local machine, I could fill in the tables through Tasks> Generate Script> Advanced Options (Include only data) but this information will change the day when the migration to Azure is done, therefore I must Do the same process.
So, is it possible to create an INSERT SELECT script so that it does not include records one by one and is as dynamic as possible? For example, you would have to generate an INSERT INTO similar to this:
SET IDENTITY_INSERT [SchemaX].[TableA] ON ;
INSERT INTO [SchemaX].[TableA]
(
[id]
,[fieldA]
,[fieldB]
,[fieldC])
SELECT
[id]
,[fieldA]
,[fieldB]
,[fieldC]
FROM [server].[dbname].[SchemaX].[TableA]
SET IDENTITY_INSERT [SchemaX].[TableA] OFF ;
Some tables have IDENTITY enabled so you would have to recognize which tables are like this and use SET IDENTITY_INSERT when inserting. This way you would have to link the production server and insert the information into the local server.
If there are suggestions or recommendations about another way you are welcome
Has been answered before ...
/****** Object: StoredProcedure [dbo].[procUtils_GenerateInsertProc] Script Date: 03/20/2010 13:06:13 ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[procUtils_GenerateInsertProc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[procUtils_GenerateInsertProc]
GO
/****** Object: StoredProcedure [dbo].[procUtils_GenerateInsertProc] Script Date: 03/20/2010 13:06:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--exec procUtils_GenerateInsertProc 'Whatever'
--exec sp_HelpText procUtils_GenerateInsertProc
CREATE PROCEDURE [dbo].[procUtils_GenerateInsertProc]
#TableName [varchar](50)
WITH EXECUTE AS CALLER
AS
BEGIN -- proc start
SET NOCOUNT ON;
BEGIN TRY --begin try
--FIRST SEARCH THE TABLE WHICH HAD A "Feature" in its name
--SELECT NAME FROM SYS.TABLES WHERE NAME LIKE '%Feature%'
--SELECT column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='Feature' --SELECT * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='Task'
--Decalre a variable to remember the position of the current delimiter
DECLARE #ProcName varchar(1000)
set #ProcName = '[dbo].[procGen_' + #TableName + '_Insert]'
DECLARE #CurrentDelimiterPositionVar INT
DECLARE #PkColumnName varchar(200)
--Decalre a variable to remember the number of rows in the table
DECLARE #Count INT
DECLARE #ColumnName varchar(300);
DECLARE #DataType varchar(50)
DECLARE #IsNullable bit
DECLARE #MaxLength INT
DECLARE #IsComputed BIT
set #IsComputed = 0
DECLARE #IsPrimaryKey BIT
set #IsPrimaryKey = 0
DECLARE #CODESTR VARCHAR(max)
--PRINT DROP PROCEDURE
set #CODESTR = ' '
--Declare the Table variable
DECLARE #ColumnNames TABLE
(
Number INT IDENTITY(1,1), --Auto incrementing Identity column
TableName varchar(300) , --the name of the table
ColumnName VARCHAR(300) , --The string value ,
DataType varchar(50) , --the datatype
IsNullable bit , --should we add =null in front
MaxLength INT , --VARCHAR(LENGHTi)
IsComputed bit , --whether or not this table is computed
IsPrimaryKey bit --whether or not this table is computed
)
--Populate the TABLE variable using some logic
-- SELECT * from INFORMATION_SCHEMA.COLUMNS
INSERT INTO #ColumnNames
(
TableName ,
ColumnName ,
DataType ,
IsNullable ,
MaxLength ,
IsComputed ,
IsPrimaryKey )
SELECT
TableName ,
ColumnName ,
DataType ,
IsNullable ,
MaxLength ,
IsComputed ,
IsPrimaryKey
from viewMeta_TableColumns
--debug where TableName = 'Whatever'
where TableName = #TableName
--SELECT column_name , Data_type , IsNullable , MaxLength
--from INFORMATION_SCHEMA.COLUMNS
--where TABLE_NAME=#TableName
--Initialize the looper variable
SET #CurrentDelimiterPositionVar = 1
--Determine the number of rows in the Table
SELECT #Count=max(Number) from #ColumnNames
--A variable to hold the currently selected value from the table
set #CODESTR = #CODESTR + 'IF OBJECT_ID(''' + #ProcName + ''') IS NOT NULL
BEGIN
DROP PROC ' + #ProcName + '
END
GO'
set #CODESTR = #CODESTR + '
/****** Object: StoredProcedure ' + #ProcName + '*/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE ' + #ProcName + '
#CurUserSessionId [int] ,
#CurPageTypeId [int] ,
#MsgOut [varchar](200) OUTPUT ,
#DebugMsgOut [varchar](200) OUTPUT,
#Ret [int] OUTPUT ,' + CHAR(13)
--#COLUMN_NAME [DATA_TYPE] (MAX_LENGTH) =NULL ,
WHILE #CurrentDelimiterPositionVar <= #Count --1st loop
BEGIN
--Load current value from the Table
SELECT #ColumnName = ColumnName FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #DataType = DataType FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #MaxLength = MaxLength FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
set #IsNullable = ( select IsNullable FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
set #IsPrimaryKey = ( select IsPrimaryKey FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
if ( #DataType = 'timestamp' or #IsComputed = 1)
begin
set #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1
continue
end
set #CODESTR = #CODESTR + '#' + #ColumnName + ' ['+ #DataType + '] '
--ADD THE (200)
IF #MaxLength IS NOT NULL
BEGIN --IF #MaxLength IS NOT NULL
--xml
if #DataType <> 'xml' and #DataType <> 'sql_variant' and
#DataType <> 'text' and #DataType <> 'ntext' and #DataType <> 'image' and
#DataType <> 'hierarchyid' and #DataType <> 'bit' and #DataType <> 'varbinary' and
#DataType <> 'int' and #DataType <> 'uniqueidentifier' and #DataType <> 'tinyint' and
#DataType <> 'timestamp' and #DataType <> 'uniqueidentifier' and #DataType <> 'smallint' and
#DataType <> 'bigint' and #DataType <> 'smallmoney' and #DataType <> 'money' and
#DataType <> 'real' and #DataType <> 'smalldatetime' and #DataType <> 'datetime'
begin --those with()
if #MaxLength <> -1
SET #CODESTR = #CODESTR + '(' + CONVERT(VARCHAR , #MaxLength ) + ')'
else
SET #CODESTR = #CODESTR + '(max)'
end --those with(200)
else
begin
SET #CODESTR = #CODESTR --DO NOTHING
end
END --IF #MaxLength IS NOT NULL
IF #IsNullable = 1
SET #CODESTR = + #CODESTR + ' = NULL '
if #IsPrimaryKey = 1
SET #CODESTR = #CODESTR + ' OUTPUT '
if #CurrentDelimiterPositionVar <> #Count
SET #CODESTR = #CODESTR + ','
--DEBUGGING
--set #CODESTR = #CODESTR + '#ColumnName - ' + #ColumnName
--set #CODESTR = #CODESTR + '#DataType - ' + #DataType
--set #CODESTR = #CODESTR + '#IsNullable - ' + #IsNullable
--set #CODESTR = #CODESTR + '#MaxLength - ' + CONVERT ( VARCHAR , #MaxLength )
set #CODESTR = #CODESTR + CHAR(13)
SET #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1
END
SET #CODESTR = #CODESTR + '
WITH EXECUTE AS CALLER
AS
BEGIN -- proc start
SET NOCOUNT ON;
BEGIN TRY --begin try
--
set #Ret = 1 --assume false from the beginning
declare #MsgKey [nvarchar](max)
declare #MsgTxt [nvarchar](max)
exec procUtils_GetMsgTxtByKeyAndUserSessionId
#UserSessionId =2 ,
#MsgKey = ''MsgOkTheAddingOfItemIsOk'' ,
#MsgTxt = ''''
set #MsgOut = replace (#MsgTxt , ''{0}'' , ''' + #TableName + ''' )
declare #thisProcName varchar(300)
set #thisProcName= ( SELECT OBJECT_NAME(##PROCID))
'
SET #CurrentDelimiterPositionVar = 1 --START LOOP AGAIN
set #CODESTR = #CODESTR + '
--Action !!!
INSERT INTO [dbo].[' + #TableName + ']( ' + CHAR(13)
--Loop through until all row processing is done
WHILE #CurrentDelimiterPositionVar <= #Count --2nd loop
BEGIN
--Load current value from the Table
SELECT #ColumnName = ColumnName FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #DataType = DataType FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #MaxLength = MaxLength FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
set #IsNullable = ( select IsNullable FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
set #IsPrimaryKey = ( select IsPrimaryKey FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
if #IsPrimaryKey = 1
begin -- the primary key
set #PkColumnName = #ColumnName
end --the primary key
if ( #DataType = 'timestamp' or #IsComputed = 1 or #IsPrimaryKey = 1 )
begin
set #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1
continue
end
--select
if #CurrentDelimiterPositionVar <= #Count
BEGIN
set #CODESTR = #CODESTR + '[' + #ColumnName + ']' --null the codestring var
if #CurrentDelimiterPositionVar <> #Count
set #CODESTR = #CODESTR + ', --type of ' + #DataType + CHAR(13) --WITH COMMA
ELSE
set #CODESTR = #CODESTR + ' --type of ' + #DataType + CHAR(13) --NO COMMA
END -- IF SHOULD PRINT COLUMN
SET #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1;
END --eof while 2
set #CODESTR = #CODESTR + ') VALUES ( '
--AND START ALL OVER AGAIN
SET #CurrentDelimiterPositionVar = 1
--Loop through until all row processing is done
WHILE #CurrentDelimiterPositionVar <= #Count --WHILE 3
BEGIN
--Load current value from the Table
SELECT #ColumnName = ColumnName FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #DataType = DataType FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #MaxLength = MaxLength FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
set #IsNullable = ( select IsNullable FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
set #IsPrimaryKey = ( select IsPrimaryKey FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
if ( #DataType = 'timestamp' or #IsComputed = 1 or #IsPrimaryKey = 1)
begin
set #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1
continue
end
set #CODESTR = #CODESTR + '#' + #ColumnName
if #CurrentDelimiterPositionVar <= #Count
BEGIN
IF #CurrentDelimiterPositionVar <> #Count
set #CODESTR = #CODESTR + ' , --type of ' + #DataType --all others with comma
else
set #CODESTR = #CODESTR + ' --type of ' + #DataType --the last one without comma
END -- IF SHOULD NOT PRINT COLUMN
--increase the counter
set #CODESTR = #CODESTR + CHAR(13)
SET #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1;
END
set nocount off
SET #CODESTR = #CODESTR + ')
SET #' + #pkColumnName + ' = ##IDENTITY
set #Ret = ##ERROR
set #DebugMsgOut = ''TODO:REMOVE INSERT OK ''
END TRY
BEGIN CATCH
EXEC #ret = [dbo].[procUtils_GetMsgTxtByKeyAndUserSessionId]
#UserSessionId = 2,
#MsgKey = N''ErrorMsgMenuRetrievalFailed'',
#MsgTxt = #MsgOut OUTPUT
set #ret = 1
set #msgOut = #MsgTxt
set #debugMsgOut = '' Error number: '' + CAST(ERROR_NUMBER() AS varchar(100)) +
''Error message: '' + ERROR_MESSAGE() + ''Error severity: '' +
CAST(ERROR_SEVERITY() AS varchar(10)) +
''Error state: '' + CAST(ERROR_STATE() AS varchar(100)) +
''XACT_STATE: '' + CAST(XACT_STATE() AS varchar(100))
-- record the error in the database
set #debugMsgOut = #debugMsgOut + #msgOut
INSERT INTO [dbo].[LogStore] ( [Date],[Thread],[Level],[Logger],[Message])
values ( getdate() , N''8'', N''DEBUG'', #thisProcName , #debugMsgOut )
END CATCH
END --procedure end
GO
'
print #codestr
END TRY --end try
BEGIN CATCH
print ' Error number: ' + CAST(ERROR_NUMBER() AS varchar(100)) +
'Error message: ' + ERROR_MESSAGE() + 'Error severity: ' +
CAST(ERROR_SEVERITY() AS varchar(1000)) +
'Error state: ' + CAST(ERROR_STATE() AS varchar(100)) +
'XACT_STATE: ' + CAST(XACT_STATE() AS varchar(100))
END CATCH
END --procedure end
--USE [Gaf]
--GO
--SELECT NAME FROM SYS.tables where name like '%Msg%'
--EXEC [dbo].[procUtils_GenerateInsertProc] #TableName = N'Whatever'
GO

Looping in a dynamic sql query

I've nearly got this dynamic query working:
DECLARE
#ord int = 1,
#wght int = 0,
#bit int,
#colname varchar(max),
#col2 varchar(max),
#sstr varchar(max),
#fstr varchar(max),
#wstr varchar(max),
#sum varchar(max) = ' 0',
#colist varchar(max) = '',
#frlist varchar(max) = '',
#whlist varchar(max) = '',
#sql varchar(max)
WHILE #wght < 2
BEGIN
SET #wght = #wght + 1
WHILE #ord < 3
BEGIN
SET #ord = #ord + 1
SELECT #colname = BR FROM dbo.[Y2 Ordinal] WHERE ORDINAL_POSITION= #ord
SET #sstr = '(A.' + #colname + '*B' + CAST(#wght AS varchar(max))+'.' + #colname +')'
SET #sum = #sum + '+' + #sstr
END
SELECT #w = [ID NO] FROM dbo.[Weightings] WHERE [ID NO]= #wght
SET #fstr = ' dbo.[Weightings] AS B' + CAST(#wght AS varchar(max))
SELECT #col2 = [Batch ID] FROM dbo.[Weightings] WHERE [ID NO]= #wght
SET #wstr = 'B' + CAST(#wght AS varchar(max)) + '.[Portfolio ID] = ' + '''' + #col2 + ''''
SET #colist = #colist + ',' +(#sum)+' AS ' +''''+(#col2)+''''
SET #frlist = #frlist + ',' +(#fstr)
SET #whlist = #whlist + ' AND ' +(#wstr)
END
SET #sql = '(SELECT A.Sim' + #colist+ ' FROM dbo.[Y2 Net of Fees] As A' + #frlist +' WHERE A.[Simulation] IS NOT NULL ' + #whlist + ')ORDER BY Simulation'
PRINT(#sql);
The output sql statement (reformatted here) is:
(SELECT A.Sim,
0+(A.[Apples]*B1.[Apples])+(A.[Oranges]*B1.[Oranges]) AS 'Batch A',
0+(A.[Apples]*B1.[Apples])+(A.[Oranges]*B1.[Oranges]) AS 'Batch B'
FROM dbo.[Fruit] As A,
dbo.[Weightings] AS B1,
dbo.[Weightings] AS B2
WHERE A.[Simulation] IS NOT NULL
AND B1.[Batch ID] = 'Batch A'
AND B2.[Batch ID] = 'Batch B')
ORDER BY Simulation
My desired output is:
SELECT A.Sim,
0+(A.[Apples]*B1.[Apples])+(A.[Oranges]*B1.[Oranges]) AS 'Batch A',
0+(A.[Apples]*B2.[Apples])+(A.[Oranges]*B2.[Oranges]) AS 'Batch B'
So my problem is the #wght remaining static in the second while loop, I was thinking the when it increased in the first loop it would feed into the second. Any suggestions?
USE APPLICATION
GO
SET NOCOUNT ON
IF OBJECT_ID('tempdb.dbo.#Y2_Ordinal') IS NOT NULL
BEGIN
DROP TABLE #Y2_Ordinal
END
IF OBJECT_ID('tempdb.dbo.#Weightings') IS NOT NULL
BEGIN
DROP TABLE #Weightings
END
GO
CREATE TABLE #Y2_Ordinal(
COLUMN_NAME VARCHAR(100)
,ORDINAL_POSITION INT
);
CREATE TABLE #Weightings(
[Batch ID] INT
,[ID NO] INT
);
GO
INSERT INTO #Y2_Ordinal
(COLUMN_NAME
,ORDINAL_POSITION)
VALUES('Apples'
,'1')
INSERT INTO #Y2_Ordinal
(COLUMN_NAME
,ORDINAL_POSITION)
VALUES('Oranges'
,'2')
--SELECT * FROM #Y2_Ordinal
--INSERT INTO #Y2_Ordinal
-- (COLUMN_NAME
-- ,ORDINAL_POSITION)
-- VALUES('Grapes'
-- ,'3')
INSERT INTO #Weightings VALUES('1','1')
INSERT INTO #Weightings VALUES('2','2')
INSERT INTO #Weightings VALUES('3','3')
DECLARE
#ord int = 1,
#wght int = 0,
#bit int,
#colname varchar(max),
#col2 varchar(max),
#sstr varchar(max),
#fstr varchar(max),
#wstr varchar(max),
#sum varchar(max) = '',
#colist varchar(max) = '',
#frlist varchar(max) = '',
#whlist varchar(max) = '',
#sql varchar(1000),
#w VARCHAR(max)
WHILE #wght < 2
BEGIN
SET #wght = #wght + 1
--PRINT(#wght)
SET #ord = 1
Set #sum = ''
WHILE #ord < 3
BEGIN
--PRINT('ord' + CAST(#ord AS VARCHAR(100)))
SELECT #colname = COLUMN_NAME FROM #Y2_Ordinal WHERE ORDINAL_POSITION= #ord
--PRINT(#colname)
SET #sstr = '(A.' + #colname + '*B' + CAST(#wght AS varchar(max))+'.' + #colname +')'
--PRINT(#sstr)
SET #sum = #sum + '+' + #sstr
--PRINT(#sum)
SET #ord = #ord + 1
END
SELECT #w = [ID NO] FROM #Weightings WHERE [ID NO]= #wght
SET #fstr = ' dbo.[Weightings] AS B' + CAST(#wght AS varchar(max))
SELECT #col2 = [Batch ID] FROM #Weightings WHERE [ID NO]= #wght
--PRINT ('col2' + #col2)
SET #wstr = 'B' + CAST(#wght AS varchar(max)) + '.[Portfolio ID] = ' + '''' + #col2 + ''''
SET #colist = #colist + ', 0' +(#sum)+' AS ' +''''+(#col2)+''''
--PRINT ('col_list' + #colist)
SET #frlist = #frlist + ',' +(#fstr)
SET #whlist = #whlist + ' AND ' +(#wstr)
END
--PRINT(#colist)
--PRINT(#frlist)
--PRINT(#whlist)
SET #sql = '(SELECT A.Sim' + #colist+ ' FROM dbo.[Y2 Net of Fees] As A'
+ #frlist +' WHERE A.[Simulation] IS NOT NULL '
+ #whlist + ')ORDER BY Simulation'
PRINT #SQL