Use a SELECT to Print a Bunch of INSERT INTOs - sql

I have a bunch of records I want to move to another database and I just want to create a bunch of inserts that I can copy and paste. I've seen someone do this before but I can't figure it out. I'm not getting the escapes right.
It's something like this where 'Code', 'Description' and 'Absent' are the columns I want from the table.
SELECT 'INSERT INTO AttendanceCodes
(Code, Description, Absent)
VALUES
(' + Code + ',' + Description + ',' + Absent')'
FROM AttendanceCodes
The end result should be a slew of INSERTS with the correct values like this:
INSERT INTO AttendanceCodes
(Code, Description, Absent)
VALUES
('A','Unverified Absence','UA')

Check this
SELECT 'INSERT INTO AttendanceCodes (Code, Description, Absent) VALUES (''' + Code + ''',''' + Description + ''',''' + Absent''')'
FROM AttendanceCodes

try something like this:
SELECT
'INSERT INTO AttendanceCodes (Code, Description, Absent) VALUES ('
+ ISNULL(''''+CONVERT(varchar(8000),Code)+'''','null')
+ ','
+ ISNULL(''''+CONVERT(varchar(8000),Description)+'''','null')
+ ','
+ ISNULL(''''+CONVERT(varchar(8000),Absent)+'''','null')
+')'
FROM AttendanceCodes
This will handle NULLs. I'm not sure of your columns data types, but you can only concatenate strings, so I forced everything to varchar(8000), you can modify this as necessary.

For a generic stored procedure that takes a table name (and some other options) and generates insert statements for current data in that table, check out this handy
link.
It creates a procedure called sp_generate_inserts. You pass this procedure the table name, and it will generate all the insert statements to recreate the data.

Related

SQL Server : exploding CSV for SELECT statement

I have a table structure as below;
id txtName intReferences
------------------------------
1 Fred 1,4,6,444,56,43,
2 Sam 5,33,5904,43
3 Tom 1200
4 Samantha 43,44,888,99
I'd like to write a T-SQL query to return all the records based on a series of numbers provided.
For example, querying for 43 would return Fred, Sam and Samantha. The catch is, when querying for 3, it shouldn't return results for Sam or Samantha, given that that isn't the number in its entirety. Looking for a direct and whole number match.
The CSV value may end in a comma.
I've tried to use the "IN" statement, but it returns results if any portion of the number exists. Ideally trying to achieve without creating a function given some database restrictions.
Use string_split():
select t.*
from t cross apply
string_split(t.intReferences, ',') s
where s.value = '3';
Then, fix your data model so your are not storing integer values in strings. This is bad, bad, bad. Here are some reasons why:
Numbers should be stored as numbers, not strings (using the correct type).
SQL Server has lousy string manipulation functions.
Only one value should be stored in a column.
Foreign key relationships should be properly declared.
Resulting queries cannot be optimized to using indexes or partitions.
SQL has a great way to store lists. It is called a table not a string.
Clearly, the best way to accommodate this situation is to have properly normalized data.
Another method for querying the data with the current structure would be to check for comma + (your number) + comma. Something like this...
Declare #Temp Table(id int, txtName varchar(200), intReferences varchar(200))
Insert Into #Temp Values(1, 'Fred', '1,4,6,444,56,43,')
Insert Into #Temp Values(2, 'Sam', '5,33,5904,43')
Insert Into #Temp Values(3, 'Tom', '1200')
Insert Into #Temp Values(4, 'Samantha', '43,44,888,99')
Select *
From #Temp
Where ',' + intReferences + ',' like '%,' + '43' + ',%'
Select *
From #Temp
Where ',' + intReferences + ',' like '%,' + '3' + ',%'

SQL Merge statement with input table name

I have a scenario to copy the data from one table to another table. While copying, I need to store the Identity values of table1 and table2.
create procedure procedure1
(#sourceClientNumber int,
#destinationClientNumber int,
#statusID varchar(10))
as
declare #scriptSql nvarchar(max);
declare #Temp_ClientScriptTable table
(newScriptID int,
oldScriptID int);
begin
SET #CreatedBy = 'Initaial Creation'
SET #CreatedByName= 'Initial Creation'
SET #CreatedDateTime = GETDATE()
SET #scriptSql = 'Merge into [dbo].[Client_'+#destinationClientNumber +'_Script] using
(select ScriptID,
ScriptName,
ScriptVersion,
Description,
FacilityID,
StatusID,
Shared,
ScriptTYpeID
from [dbo].[Client_'+#sourceClientNumber +'_Script]
where statusID = ' +#statusID + '
) scripts on 1 = 0
When not matched then
insert ([ScriptName],
[ScriptVersion],
[CreatedBy],
[CreatedByName],
[CreatedDateTime],
[Description],
[FacilityID],
[StatusID],
[Shared],
[ScriptTypeID])
values (scripts.ScriptName,
scripts.ScriptVersion,'
+ #CreatedBy + ','
+ #CreatedByName + ','
+ #CreatedDateTime + ',
scripts.Description,
scripts.FacilityID,
scripts.StatusID,
scripts.Shared,
scripts.ScriptTypeID)
output Inserted.ScriptID, scripts.ScriptID
into' + #Temp_ClientScriptTable + '(newScriptID, oldScriptID)'
EXECUTE sp_executesql #scriptSql
I am getting the error at #Temp_ClientScriptTable.
Could you please help me on this..
The main problem here is faulty database design.
The fact that you have multiple tables with the same structure, only different by a number inside the name - means you are mixing data (the number) and meta data (the table name).
Instead of having a different table for each client, you should add the client number as a column to a single table.
If you can do that, it will also eliminate the need for using dynamic SQL everywhere you need to address this table.
Root cause is, #Temp_ClientScriptTable is a table variable and cannot participate in string concatenation.
Your last line of #scriptSql should be -
into #Temp_ClientScriptTable(newScriptID, oldScriptID)'
instead of
into' + #Temp_ClientScriptTable + '(newScriptID, oldScriptID)'
Also you need to add single quotes around varchar variables while using them in string concatenation. Your final #scriptSql will be -
SET #scriptSql = 'Merge into [dbo].[Client_'+#destinationClientNumber +'_Script] using
(select ScriptID,
ScriptName,
ScriptVersion,
Description,
FacilityID,
StatusID,
Shared,
ScriptTYpeID
from [dbo].[Client_'+#sourceClientNumber +'_Script]
where statusID = ''' +#statusID + '''
) scripts on 1 = 0
When not matched then
insert ([ScriptName],
[ScriptVersion],
[CreatedBy],
[CreatedByName],
[CreatedDateTime],
[Description],
[FacilityID],
[StatusID],
[Shared],
[ScriptTypeID])
values (scripts.ScriptName,
scripts.ScriptVersion,'''
+ #CreatedBy + ''','''
+ #CreatedByName + ''','
+ #CreatedDateTime + ',
scripts.Description,
scripts.FacilityID,
scripts.StatusID,
scripts.Shared,
scripts.ScriptTypeID)
output Inserted.ScriptID, scripts.ScriptID
into #Temp_ClientScriptTable(newScriptID, oldScriptID)'
To debug these kind of issue, you should always print the the concatenated query and see how your query will look like -
print #scriptSql

Insert query where one field is a dynamic list of values

I'm looking to solve the challenge of having an insert query where action_key is a dynamic list of strings. The cust_name and action fields will be the same for each new row, but action_key will change depending on how many action keys are in the list. Example:
INSERT INTO [table_name] (cust_name, action, action_key) VALUES (Bob, Approve, ApproveId1)
INSERT INTO [table_name] (cust_name, action, action_key) VALUES (Bob, Approve, ApproveId2) etc.
I'd appreciate some insight on this topic, thanks.
You'll have to play with it, but based upon your XML structure input that's how I handled the parsing.
Declare #cust_name Varchar(50),
#action Varchar(50),
#action_key Varchar(1000)
Select #cust_name = 'Bob',
#action = 'Approve',
#action_key = '<action_keys><action_key>ApproveId1</action_key><action_key>ApproveId2</action_key><action_key>ApproveId3</action_key><action_key>ApproveId4</action_key></action_keys>'
Select #cust_name,
#action,
n.r.value('.', 'varchar(50)')
From (Select Cast(#action_key As Xml)) As s(XMLCol)
Cross Apply s.XMLCol.nodes('action_keys/action_key') as n(r)
Reference: How Do I Split a Delimited String in SQL Server Without Creating a Function?
Well, you don't say how you get the list of strings, but generally you could create a SQL string dynamically and execute it:
EXEC ('INSERT INTO [table_name] ' +
'(cust_name, action, ' + action_key + ') ' +
'VALUES (''Bob'', ''Approve'', ''ApproveId1'')')

Convert comma-separated list of values into a single comma-separated string?

How to convert this:
('xxx','yyy','zzz')
Into this:
('xxx,yyy,zzz')
Using T-SQL?
DECLARE #x VARCHAR(32) = '''xxx'',''yyy'',''zzz''';
SELECT REPLACE(#x, ''',''', ',');
If all you want to do is concatenate then you can do:
SELECT #param1 + ',' + #param2 + ',' ... + #param30;
However that is just silly IMHO. This is like washing each of your socks separately.
I have to question what you're going to do with the value now... if these are separate entities why are they comma-separated in the first place? Perhaps you should look into table-valued parameters instead of this comma-separated values nonsense, then you can use the values in a set-based way right from the start.
by concatenating the values (which means individual columns)?
SELECT (col1 + ',' + col2+ ',' + col3)
FROM tableName

new line in SQL insert query

I want to use the following statement to add a row in a table named people with one column which is varchar(100)
insert into people values ('a b')
I want to have a new line between a and b.
How to do this?
I tried something like 'a CHAR(13) b' but did not work.
Thanks.
How about
'a ' + CHAR(13) + ' b'
This works as well:
'a' + CRLF + 'b'
Check this link as well
How to insert a line break in a SQL Server VARCHAR/NVARCHAR string