How to execute query (update) stored in table (query)? - sql-server

I'm trying to execute the result of this query.
SELECT 'UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] ' + 'SET [' + COLUMN_NAME + '] = RTRIM(LTRIM(SUBSTRING ([' + COLUMN_NAME + '], 2 , LEN ([' + COLUMN_NAME + ']) - 2) )) WHERE LEFT([' + COLUMN_NAME + '], 1) = ' + '''"''' + ' AND RIGHT([' + COLUMN_NAME + '], 1) = ' + '''"'''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE IN ('varchar', 'nvarchar')
ORDER BY TABLE_NAME, COLUMN_NAME
It return more one row. For example:
UPDATE [dbo].[ACCDB] SET [ACODI] = RTRIM(LTRIM(SUBSTRING ([ACODI], 2 , LEN ([ACODI]) - 2) )) WHERE LEFT([ACODI], 1) = '"' AND RIGHT([ACODI], 1) = '"'
UPDATE [dbo].[ANAGP] SET [CDIVA] = RTRIM(LTRIM(SUBSTRING ([CDIVA], 2 , LEN ([CDIVA]) - 2) )) WHERE LEFT([CDIVA], 1) = '"' AND RIGHT([CDIVA], 1) = '"'
Now, how I execute this row programmatically? Without I write every row in stored procedure?
Thanks, I wait answer.

What you're trying to do here is dynamic SQL; building your queries on the fly. There are a number of ways to do that. Since you're building multiple statements, you need to be able to execute them one at a time. McNets's answer suggests using a cursor, which is one common way to do what you're after. Another way is to break up your statements with a loop, then execute them one after the other.
The code below gets a list of table names first, defining how many statements we may end up with. Mostly, the ID column is what we care about here. Then there's a WHILE loop to run your query once for each table, with a check to make sure we need to execute the statement for that table.
DECLARE #SqlText NVARCHAR(2000) --Variable to hold your query
,#Counter INT --Counter to keep track of where we are in the loop
,#EndLoop INT; --Value to stop the loop
DECLARE #TblList TABLE (
[ID] INT IDENTITY(1,1)
,[Schema] NVARCHAR(128)
,[Table] NVARCHAR(128));
INSERT INTO #TblList ([Schema],[Table])
SELECT
TABLE_SCHEMA
,TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES;
SELECT #Counter = MIN([ID]), #EndLoop = MAX([ID])
FROM #TblList;
WHILE #Counter <= #EndLoop
BEGIN
IF EXISTS ( --If there are no character columns, skip the table
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS AS col JOIN #TblList AS tbl
ON tbl.[Schema] = col.TABLE_SCHEMA
AND tbl.[Table] = col.TABLE_NAME
AND tbl.[ID] = #Counter
AND col.DATA_TYPE IN ('varchar', 'nvarchar')
)
BEGIN
--Construct the query
SELECT #SqlText = CAST('UPDATE [' + col.TABLE_SCHEMA + '].[' + col.TABLE_NAME + '] ' + 'SET [' + col.COLUMN_NAME + '] = RTRIM(LTRIM(SUBSTRING ([' + col.COLUMN_NAME + '], 2 , LEN ([' + col.COLUMN_NAME + ']) - 2) )) WHERE LEFT([' + col.COLUMN_NAME + '], 1) = ' + '''"''' + ' AND RIGHT([' + col.COLUMN_NAME + '], 1) = ' + '''"''' AS NVARCHAR(2000))
FROM INFORMATION_SCHEMA.COLUMNS AS col
JOIN #TblList AS tbl
ON tbl.[Schema] = col.TABLE_SCHEMA
AND tbl.[Table] = col.TABLE_NAME
AND tbl.[ID] = #Counter
AND col.DATA_TYPE IN ('varchar', 'nvarchar');
--Run the query
EXEC sp_executesql #SQL;
END
--Increment the counter to move through the table list
SET #Counter = #Counter + 1;
END

I'd suggest to use a CURSOR to execute it line by line.
Have a look at one o my answers on dba.stackexchange.com for a similar question.
Restore all IDENTITY seeds (out of sync since database restore)

DECLARE #c_Statement VARCHAR(MAX)
DECLARE StatementCursor CURSOR FOR
SELECT 'UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] ' + 'SET [' + COLUMN_NAME + '] = RTRIM(LTRIM(SUBSTRING ([' + COLUMN_NAME + '], 2 , LEN ([' + COLUMN_NAME + ']) - 2) )) WHERE LEFT([' + COLUMN_NAME + '], 1) = ' + '''"''' + ' AND RIGHT([' + COLUMN_NAME + '], 1) = ' + '''"'''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE IN ('varchar', 'nvarchar')
ORDER BY TABLE_NAME, COLUMN_NAME
OPEN StatementCursor
FETCH NEXT FROM StatementCursor INTO #c_Statement
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC(#c_Statement)
FETCH NEXT FROM StatementCursor INTO #c_Statement
END
CLOSE StatementCursor
DEALLOCATE StatementCursor
You may wanna check QUOTENAME() function to wrap object names in quotes instead of hard-coding them in the expression. You also need to check for errors (TRY/CATCH) and validate your user permissions to update the resulting rows.
If you have multiple databases, INFORMATION_SCHEMA.COLUMNS will only list the ones from the current connection.

Related

How do I Get Maximum and Minimum Data Length for All Columns on All Tables in a SQL Server database Using One Query?

I am currently trying to get details of maximum and minimum data length (using DATALENGTH / LEN) for all columns on all tables on my SQL Server database.
Currently what I can do is I can show the details of the actual length of a column when setting up the table, maximum and minimum data length but only for one table.
I have about 50 tables that I want to check, so instead of checking each table one by one, could anyone assist in getting the result for all tables within one single query?
This is the query that I currently use (I found the query from an online source):
DECLARE #TSQL VARCHAR(MAX) = ''
DECLARE #TableName sysname = 'MyTable'
SELECT #TSQL = #TSQL + 'SELECT ' + QUOTENAME(sc.name, '''') + ' AS ColumnName,
' + QUOTENAME(t.name, '''') + ' AS DataType, ' +
QUOTENAME(sc.max_length, '''') + ' AS ActualLength,
MIN(DATALENGTH(' + QUOTENAME(sc.name) + ')) AS MinUsedLength,
MAX(DATALENGTH(' + QUOTENAME(sc.name) + ')) AS MaxUsedLength FROM '+#TableName+ char(10) +' UNION '
FROM sys.columns sc
JOIN sys.types t on t.system_type_id = sc.system_type_id and t.name != 'sysname'
WHERE sc.OBJECT_ID = OBJECT_ID(#TableName)
SET #TSQL = LEFT(#TSQL, LEN(#TSQL)-6)
EXEC(#TSQL)
DECLARE #SQL NVARCHAR(max) = N'';
SELECT #SQL = #SQL + N'SELECT '''
+ C.TABLE_SCHEMA + N''' AS TABLE_SCHEMA, '''
+ C.TABLE_NAME + N''' AS TABLE_NAME, '''
+ C.COLUMN_NAME + N''' AS COLUMN_NAME, '
+ N'MIN(DATALENGTH([' + C.COLUMN_NAME + N'])) AS MIN_LENGTH, '
+ N'MAX(DATALENGTH([' + C.COLUMN_NAME + N'])) AS MAX_LENGTH '
+ N'FROM [' + + C.TABLE_SCHEMA + N'].[' + C.TABLE_NAME
+N'] UNION ALL '
FROM INFORMATION_SCHEMA.TABLES AS T
JOIN INFORMATION_SCHEMA.COLUMNS AS C
ON T.TABLE_SCHEMA = C.TABLE_SCHEMA AND
T.TABLE_NAME = C.TABLE_NAME
WHERE TABLE_TYPE = 'BASE TABLE';
SET #SQL = LEFT(#SQL, LEN(#SQL) - 10);
EXEC (#SQL);

Verify SQL Server trigger is capturing all record changes

We are trying to track down record changes in a SQL Server table. Users are complaining they change a record in the morning and when they return in the afternoon, the value is changed back.
Example: column value was null. User changed to a value like 6. When they return to the record, the value might be null again or zero.
We turned on auditing in SQL Server, but I am not seeing the first edit (am) or the change back to null or zero. Yes, I am thinking user error but before I blame a user, I need to eliminate all other possibilities. I pulled a trigger event code from the web and modified it for my purposes. I put it on the specific table under triggers. It is pulling records as I expected. It keep track of what columns were changed, the old and the new values. I will admit I am not intimate with everything this code is doing so I want to ask if this code has any potential holes.
Example: would it not record an event if someone changed a column from 1 to NULL because of the NULL? ModifiedOn and ModifiedBy should be autofilled when the program saves a record. The trigger will capture the ModifiedOn but not consistently the ModifiedBy. A question was raised if ModifiedBy old value and new value matched (same person made both changes), would it not a record to the log the ModifiedBy because the values matched.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[TR_AppointmentBase_LOG]
ON [dbo].[AppointmentBase]
FOR UPDATE
AS
DECLARE #bit INT,
#field INT,
#maxfield INT,
#char INT,
#fieldname VARCHAR(128),
#TableName VARCHAR(128),
#PKCols VARCHAR(1000),
#sql VARCHAR(2000),
#UpdateDate VARCHAR(21),
#UserName VARCHAR(128),
#Type CHAR(1),
#PKSelect VARCHAR(1000),
#PKSelect2 VARCHAR(1000)
--You will need to change #TableName to match the table to be audited.
-- Here we made GUESTS for your example.
SELECT #TableName = 'AppointmentBase'
SELECT #UserName = SYSTEM_USER,
#UpdateDate = CONVERT(NVARCHAR(30), GETDATE(), 126)
-- Action
IF EXISTS (
SELECT *
FROM INSERTED
)
IF EXISTS (
SELECT *
FROM DELETED
)
SELECT #Type = 'U'
ELSE
SELECT #Type = 'I'
ELSE
SELECT #Type = 'D'
-- get list of columns
SELECT * INTO #ins
FROM INSERTED
SELECT * INTO #del
FROM DELETED
-- Get primary key columns for full outer join
SELECT #PKCols = COALESCE(#PKCols + ' and', ' on')
+ ' i.[' + c.COLUMN_NAME + '] = d.[' + c.COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = #TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
-- Get primary key select for insert
SELECT #PKSelect = COALESCE(#PKSelect + '+', '')
+ '''<[' + COLUMN_NAME
+ ']=''+convert(varchar(100),
coalesce(i.[' + COLUMN_NAME + '],d.[' + COLUMN_NAME + ']))+''>''',
#PKSelect2 = COALESCE(#PKSelect2 + '+', '')
+ '+convert(varchar(100), coalesce(i.[' + COLUMN_NAME + '],d.[' + COLUMN_NAME + ']))'
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = #TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
IF #PKCols IS NULL
BEGIN
RAISERROR('no PK on table %s', 16, -1, #TableName)
RETURN
END
SELECT #field = 0,
-- #maxfield = MAX(COLUMN_NAME)
#maxfield = -- FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = #TableName
MAX(
COLUMNPROPERTY(
OBJECT_ID(TABLE_SCHEMA + '.' + #TableName),
COLUMN_NAME,
'ColumnID'
)
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
WHILE #field < #maxfield
BEGIN
SELECT #field = MIN(
COLUMNPROPERTY(
OBJECT_ID(TABLE_SCHEMA + '.' + #TableName),
COLUMN_NAME,
'ColumnID'
)
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
AND COLUMNPROPERTY(
OBJECT_ID(TABLE_SCHEMA + '.' + #TableName),
COLUMN_NAME,
'ColumnID'
) > #field
SELECT #bit = (#field - 1)% 8 + 1
SELECT #bit = POWER(2, #bit - 1)
SELECT #char = ((#field - 1) / 8) + 1
IF SUBSTRING(COLUMNS_UPDATED(), #char, 1) & #bit > 0
OR #Type IN ('I', 'D')
BEGIN
SELECT #fieldname = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
AND COLUMNPROPERTY(
OBJECT_ID(TABLE_SCHEMA + '.' + #TableName),
COLUMN_NAME,
'ColumnID'
) = #field
SELECT #sql =
'
insert into AppointmentBase_Log2 ( Type,
TableName,
PK,
FieldName,
OldValue,
NewValue,
UpdateDate,
UserName)
select ''' + #Type + ''','''
+ #TableName + ''',' + #PKSelect2
+ ',''' + #fieldname + ''''
+ ',convert(varchar(1000),d.' + #fieldname + ')'
+ ',convert(varchar(1000),i.' + #fieldname + ')'
+ ',''' + #UpdateDate + ''''
+ ',''' + #UserName + ''''
+ ' from #ins i full outer join #del d'
+ #PKCols
+ ' where i.' + #fieldname + ' <> d.' + #fieldname
+ ' or (i.' + #fieldname + ' is null and d.'
+ #fieldname
+ ' is not null)'
+ ' or (i.' + #fieldname + ' is not null and d.'
+ #fieldname
+ ' is null)'
EXEC (#sql)
END
END
Users and managers are thinking I am not finding all the changes to the table with my code. Basically because I can not prove they changed the record in the first place let alone the second change. Based on my limited knowledge of the process above, I am not confident enough to say they are wrong.
Is there a transaction that could update a record in the table that this code could miss? Say a scheduled maintenance task that might not trigger the "U","D" or "I" types this uses. Or maybe a batch injection from an outside source?
Or, do you think I'm good with the above and should look at the user or GUI interface as not completing the transaction.

Using sub-query to generate case statements

What i am trying to accomplish is comparing two rows to each other pointing out the differences from row to row. Each row has quite a few columns and I was trying to make it easily visible for which ones had changed. Code below is my thoughts, but I know this won't work, but is a start.
SELECT
(SELECT concat('Case WHEN T1.', column_name, ' <> T2.', column_name, ' THEN ''', column_name, ' Changed Values('' + CONVERT(varchar(100), T1.', column_name, ') + '', '' + CONVERT(varchar(100), T2.', column_name, ') + '')'' ELSE '''' END AS ', column_name)
FROM information_schema.columns
WHERE table_name = 'Table')
FROM
(
SELECT * FROM Table
WHERE ID = '13'
) AS T1
JOIN
(
SELECT * FROM Table
WHERE ID = '2006'
) AS T2
ON T1.CreateTimeStamp = T2.CreateTimeStamp
I got the idea because below this works fine, but I would like this to be potentially reusable code for other table without having to type out tens or hundreds of columns each time.
SELECT
Case WHEN T1.R1<> T2.R1 THEN 'Changed Values(' + CONVERT(varchar(100),T1.R1) + ', ' + CONVERT(varchar(100),T2.R1) + ')' ELSE '' END AS R1,
Case WHEN T1.R2<> T2.R2 THEN 'Changed Values(' + CONVERT(varchar(100),T1.R2) + ', ' + CONVERT(varchar(100),T2.R2) + ')' ELSE '' END AS R2
FROM
(
SELECT * FROM Table
WHERE ID = '13'
) AS T1
JOIN
(
SELECT * FROM Table
WHERE ID = '2006'
) AS T2
ON T1.CreateTimeStamp = T2.CreateTimeStamp
For the this example please assume CreateTimeStamp always equals each other between the two rows.
You would need to create the whole query as dynamic SQL. Note that I'm using QUOTENAME() to prevent SQL Injection from weirdly named columns. I'm also trying to keep a format for the code, so I won't get headaches when debugging.
DECLARE #SQL NVARCHAR(MAX);
SELECT #SQL = N' SELECT ' + NCHAR(10)
--Concatenate all columns except ID and CreateTimeStamp
+ STUFF(( SELECT REPLACE( CHAR(9) + ',CASE WHEN T1.<<ColumnName>> <> T2.<<ColumnName>> ' + CHAR(10)
+ CHAR(9) + CHAR(9) + 'THEN ''Changed Values('' + CONVERT(varchar(100),T1.<<ColumnName>>) + '', '' + CONVERT(varchar(100),T2.<<ColumnName>>) + '')'' ' + CHAR(10)
+ CHAR(9) + CHAR(9) + 'ELSE '''' END AS <<ColumnName>>', '<<ColumnName>>', QUOTENAME(COLUMN_NAME)) + NCHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Table'
AND COLUMN_NAME NOT IN( 'ID', 'CreateTimeStamp')
FOR XML PATH(''), TYPE).value('./text()[1]', 'nvarchar(max)'), 2, 1, '') + NCHAR(10)
--Add rest of the query
+ 'FROM Table AS T1 ' + NCHAR(10)
+ 'JOIN Table AS T2 ON T1.CreateTimeStamp = T2.CreateTimeStamp ' + NCHAR(10)
+ 'WHERE ID = #ID1 ' + NCHAR(10)
+ 'AND ID = #ID2;'
--PRINT for debugging purposes
PRINT #SQL;
--Execute the dynamic built code
EXECUTE sp_executesql #SQL,
N'#ID1 int, #ID2 int',
#ID1 = 13,
#ID2 = 2006;
The concatenation method is explained on this article.

Search for special characters in records in database

I have a database in SQL Server with 100 tables inside it.
I need to write a query that parses all the rows in all the columns in all 100 tables and returns the rows that have the special characters %,#.
How do I write a query that parses all the rows in all the tables?
Maybe not so subtle solution, but is functional:
USE TSQL2012
GO
DECLARE #ColumnName VARCHAR (50)
DECLARE #TableName VARCHAR (50)
DECLARE #SchemaName VARCHAR (50)
DECLARE #SQLQuery NVARCHAR (200)
DECLARE findSpecialCharacters CURSOR
FOR
SELECT c.name, o.name, s.name from sys.columns c
INNER JOIN sys.objects o ON c.object_id = o.object_id
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE o.type = 'U'
OPEN findSpecialCharacters
FETCH NEXT FROM findSpecialCharacters
INTO #ColumnName, #TableName, #SchemaName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQLQuery =
'SELECT ' + #ColumnName + ', * FROM ' +
#SchemaName + '.' + #TableName +
' WHERE (' + #ColumnName + ' LIKE ' +
CHAR(39) + CHAR(37) + '[,]' + CHAR(37) + CHAR(39) + ') OR (' +
#ColumnName + ' LIKE ' +
CHAR(39) + CHAR(37) + '[#]' + CHAR(37) + CHAR(39) + ') OR (' +
#ColumnName + ' LIKE ' +
CHAR(39) + CHAR(37) + '[%]' + CHAR(37) + CHAR(39) + ')'
PRINT 'Table: ' + #TableName + '; Column: ' + #ColumnName
PRINT #SQLQuery
EXEC sp_executesql #SQLQuery
FETCH NEXT FROM findSpecialCharacters
INTO #ColumnName, #TableName, #SchemaName
END
CLOSE findSpecialCharacters
DEALLOCATE findSpecialCharacters
First, I was searching for all columns in all tables, and that result set put in FOR SELECT cursor statement. If table has five columns, then my cursor will create five different result set, depending on which column is WHERE filter.
But, for distinction on which column is searching, I simple put that column as first in select list.

How can I generate an INSERT script for an existing SQL Server table that includes all stored rows?

I'm looking for a way to generate a "Create and insert all rows" script with SQL Management Studio 2008 R2.
I know that I can create a "create table" script.
I can also create an "insert in" script, but that will only generate a single row with placeholders.
Is there a way to generate an insert script that contains all currently stored rows?
Yes, but you'll need to run it at the database level.
Right-click the database in SSMS, select "Tasks", "Generate Scripts...". As you work through, you'll get to a "Scripting Options" section. Click on "Advanced", and in the list that pops up, where it says "Types of data to script", you've got the option to select Data and/or Schema.
This script generates insert statements of your existing data. This is a stored procedure which you need to run once and then it is tailor made for you.
I tried to find this kind of stuff for a while but wasn't satisfied with the results, so I wrote this stored procedure.
Example:
Exec [dbo].[INS] 'Dbo.test where 1=1'
(1) Here dbo is schema and test is tablename and 1=1 is condition.
Exec [dbo].[INS] 'Dbo.test where name =''neeraj''' * for string
(2) Here dbo is schema and test is tablename and name='neeraj' is condition.
Here is the stored procedure
/*
Authore : neeraj prasad sharma (please dont remove this :))
Example (1) Exec [dbo].[INS] 'Dbo.test where 1=1'
(2) Exec [dbo].[INS] 'Dbo.test where name =''neeraj''' * for string
here Dbo is schema and test is tablename and 1=1 is condition
*/
CREATE procedure [dbo].[INS]
(
#Query Varchar(MAX)
)
AS
SET nocount ON
DECLARE #WithStrINdex as INT
DECLARE #WhereStrINdex as INT
DECLARE #INDExtouse as INT
DECLARE #SchemaAndTAble VArchar(270)
DECLARE #Schema_name varchar(30)
DECLARE #Table_name varchar(240)
DECLARE #Condition Varchar(MAX)
SET #WithStrINdex=0
SELECT #WithStrINdex=CHARINDEX('With',#Query )
, #WhereStrINdex=CHARINDEX('WHERE', #Query)
IF(#WithStrINdex!=0)
SELECT #INDExtouse=#WithStrINdex
ELSE
SELECT #INDExtouse=#WhereStrINdex
SELECT #SchemaAndTAble=Left (#Query,#INDExtouse-1)
SELECT #SchemaAndTAble=Ltrim (Rtrim( #SchemaAndTAble))
SELECT #Schema_name= Left (#SchemaAndTAble, CharIndex('.',#SchemaAndTAble )-1)
, #Table_name = SUBSTRING( #SchemaAndTAble , CharIndex('.',#SchemaAndTAble )+1,LEN(#SchemaAndTAble) )
, #CONDITION=SUBSTRING(#Query,#WhereStrINdex+6,LEN(#Query))--27+6
DECLARE #COLUMNS table (Row_number SmallINT , Column_Name VArchar(Max) )
DECLARE #CONDITIONS as varchar(MAX)
DECLARE #Total_Rows as SmallINT
DECLARE #Counter as SmallINT
DECLARE #ComaCol as varchar(max)
SELECT #ComaCol=''
SET #Counter=1
SET #CONDITIONS=''
INSERT INTO #COLUMNS
SELECT Row_number()Over (Order by ORDINAL_POSITION ) [Count], Column_Name
FROM INformation_schema.columns
WHERE Table_schema=#Schema_name AND table_name=#Table_name
SELECT #Total_Rows= Count(1)
FROM #COLUMNS
SELECT #Table_name= '['+#Table_name+']'
SELECT #Schema_name='['+#Schema_name+']'
While (#Counter<=#Total_Rows )
begin
--PRINT #Counter
SELECT #ComaCol= #ComaCol+'['+Column_Name+'],'
FROM #COLUMNS
WHERE [Row_number]=#Counter
SELECT #CONDITIONS=#CONDITIONS+ ' + Case When ['+Column_Name+'] is null then ''Null'' Else '''''''' + Replace( Convert(varchar(Max),['+Column_Name+'] ) ,'''''''','''' ) +'''''''' end+'+''','''
FROM #COLUMNS
WHERE [Row_number]=#Counter
SET #Counter=#Counter+1
End
SELECT #CONDITIONS=Right(#CONDITIONS,LEN(#CONDITIONS)-2)
SELECT #CONDITIONS=LEFT(#CONDITIONS,LEN(#CONDITIONS)-4)
SELECT #ComaCol= substring (#ComaCol,0, len(#ComaCol) )
SELECT #CONDITIONS= '''INSERT INTO '+#Schema_name+'.'+#Table_name+ '('+#ComaCol+')' +' Values( '+'''' + '+'+#CONDITIONS
SELECT #CONDITIONS=#CONDITIONS+'+'+ ''')'''
SELECT #CONDITIONS= 'Select '+#CONDITIONS +'FRom ' +#Schema_name+'.'+#Table_name+' With(NOLOCK) ' + ' Where '+#Condition
print(#CONDITIONS)
Exec(#CONDITIONS)
Yes, use the commercial but inexpensive SSMS Tools Pack addin which has a nifty "Generate Insert statements from resultsets, tables or database" feature
Just to share, I've developed my own script to do it. Feel free to use it. It generates "SELECT" statements that you can then run on the tables to generate the "INSERT" statements.
select distinct 'SELECT ''INSERT INTO ' + schema_name(ta.schema_id) + '.' + so.name + ' (' + substring(o.list, 1, len(o.list)-1) + ') VALUES ('
+ substring(val.list, 1, len(val.list)-1) + ');'' FROM ' + schema_name(ta.schema_id) + '.' + so.name + ';'
from sys.objects so
join sys.tables ta on ta.object_id=so.object_id
cross apply
(SELECT ' ' +column_name + ', '
from information_schema.columns c
join syscolumns co on co.name=c.COLUMN_NAME and object_name(co.id)=so.name and OBJECT_NAME(co.id)=c.TABLE_NAME and co.id=so.object_id and c.TABLE_SCHEMA=SCHEMA_NAME(so.schema_id)
where table_name = so.name
order by ordinal_position
FOR XML PATH('')) o (list)
cross apply
(SELECT '''+' +case
when data_type = 'uniqueidentifier' THEN 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '])+'''''''' END '
WHEN data_type = 'timestamp' then '''''''''+CONVERT(NVARCHAR(MAX),CONVERT(BINARY(8),[' + COLUMN_NAME + ']),1)+'''''''''
WHEN data_type = 'nvarchar' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+REPLACE([' + COLUMN_NAME + '],'''''''','''''''''''')+'''''''' END'
WHEN data_type = 'varchar' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+REPLACE([' + COLUMN_NAME + '],'''''''','''''''''''')+'''''''' END'
WHEN data_type = 'char' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+REPLACE([' + COLUMN_NAME + '],'''''''','''''''''''')+'''''''' END'
WHEN data_type = 'nchar' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+REPLACE([' + COLUMN_NAME + '],'''''''','''''''''''')+'''''''' END'
when DATA_TYPE='datetime' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '],121)+'''''''' END '
when DATA_TYPE='datetime2' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '],121)+'''''''' END '
when DATA_TYPE='date' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '],121)+'''''''' END '
when DATA_TYPE='datetimeoffset' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '],121)+'''''''' END '
when DATA_TYPE='geography' and column_name<>'Shape' then 'ST_GeomFromText(''POINT('+column_name+'.Lat '+column_name+'.Long)'') '
when DATA_TYPE='geography' and column_name='Shape' then '''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '])+'''''''''
when DATA_TYPE='bit' then '''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '])+'''''''''
when DATA_TYPE='xml' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+REPLACE(CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + ']),'''''''','''''''''''')+'''''''' END '
when DATA_TYPE='text' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+REPLACE(CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + ']),'''''''','''''''''''')+'''''''' END '
WHEN DATA_TYPE='image' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+CONVERT(NVARCHAR(MAX),CONVERT(VARBINARY(MAX),[' + COLUMN_NAME + ']),1)+'''''''' END '
WHEN DATA_TYPE='varbinary' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '],1)+'''''''' END '
WHEN DATA_TYPE='binary' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '],1)+'''''''' END '
when DATA_TYPE='time' then 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE ''''''''+CONVERT(NVARCHAR(MAX),[' + COLUMN_NAME + '])+'''''''' END '
ELSE 'CASE WHEN [' + column_name+'] IS NULL THEN ''NULL'' ELSE CONVERT(NVARCHAR(MAX),['+column_name+']) END' end
+ '+'', '
from information_schema.columns c
join syscolumns co on co.name=c.COLUMN_NAME and object_name(co.id)=so.name and OBJECT_NAME(co.id)=c.TABLE_NAME and co.id=so.object_id and c.TABLE_SCHEMA=SCHEMA_NAME(so.schema_id)
where table_name = so.name
order by ordinal_position
FOR XML PATH('')) val (list)
where so.type = 'U'

Resources