I'll do my best to explain:
Copy all rows that exist in current database
Mass replace a specific string value in every row that contains a specific field
Insert the copied rows
Not sure what approach to take other than hammering out sql scripts.
Thanks!
Is this as simple as creating an Data Flow Source, selecting all the rows, then passing them to a Derived Column transformation, which would be along the lines of:
REPLACE( [ColumnName], "SpecificValue", "ReplacementValue" )
and then insert these rows into your destination table using the relevant Data Flow Destination.
I may be misunderstanding or simplifying step 2...
Assuming you have a table called "table2" and that table consists of the columns facilabbr, unitname, and sortnum... You can select all rows into a temporary table (# signifies a temporary table) changing the "unitname" column to something else...You'll be left with the new values in the temporary table. You can then replace the values in your initial table if you want.
INSERT INTO #temptable1
SELECT facilabbr,
'myNewUnitName' as unitname,
sortnum
FROM table2
DELETE FROM table2
INSERT INTO table2
SELECT facilabbr,
unitname,
sortnum
FROM #temptable1
--THIS QUERY IS ONLY EQUIPPED TO HANDLE:
--SIMPLE NUMERICS SUCH AS FLOATS, INTS, ETC
--SIMPLE STRING DATA TYPES LIMITED TO: VARCHARS, CHARS, NCHARS AND NVARCHARS
--DATES AND DATETIMES
Create Procedure SQLCloner
#TableName as VarChar(max), -- Table that holds data to clone.
#NewTableName as VarChar(max) = '', -- Table to Insert into. If same as Tablename leave blank or write ''.
#VarCharFind as VarChar(max) = '', -- Value to find (In order to replace). If you aren't replacing leave blank or write ''.
#VarCharReplace as VarChar(max) = '', -- Value to replace. If you aren't replacing leave blank or write ''.
#OptionalParam As VarChar(Max) = '' -- Your WHERE clause. If you have none leave blank or write ''.
AS
Declare #index as int = 1
Declare #rowcount As Int = 0
Declare #execFunction As VarChar(max) = ''
Declare #InsertTableRowName As VarChar(max) = ''
Declare #TempFilterType As VarChar(Max) = ''
--Create RowCount of Table
Select #ROWCOUNT = Count(*)
From (
Select Column_Name
From INFORMATION_SCHEMA.COLUMNS
Where Table_Name = '' + #TableName + ''
) As TheCount
--Use While Loop to create Table Columns
While #index <= #rowcount
Begin
--Determines the Variable type to change the exec function accordingly
Select #TempFilterType = TypeTable.DATA_TYPE
From (
Select Data_Type,
ROW_NUMBER() OVER (Order By Ordinal_Position) as RowNum
From INFORMATION_SCHEMA.COLUMNS
Where Table_Name = #TableName
) As TypeTable
Where TypeTable.RowNum = #index
--Prepares #InsertTableRowName With the first part of the string
Set #InsertTableRowName = Case
When #TempFilterType IN('varchar', 'nvarchar','char', 'nchar')
Then #InsertTableRowName + ''''''''' + '
When #TempFilterType IN('datetime', 'date')
Then #InsertTableRowName + ''''''''' + Convert(varchar(Max), '
Else
#InsertTableRowName + 'Convert(varchar(Max), '
End
--Determines the Name of the Column
Select #InsertTableRowName = #InsertTableRowName +
Case
When #TempFilterType IN('varchar', 'nvarchar','char', 'nchar')
Then 'ISNULL(' + 'Replace(' + Column_Name + ','''''''','''''''''''')' + ','''')'
When #TempFilterType IN('datetime', 'date')
Then 'ISNULL(' + 'Replace(' + Column_Name + ','''''''','''''''''''')' + ',''12/31/9999'')'
Else
'ISNULL(' + 'Replace(' + Column_Name + ','''''''','''''''''''')' + ',0)'
End
From (
Select Column_Name,
ROW_NUMBER() OVER (Order By Ordinal_Position) As RowNum
From INFORMATION_SCHEMA.COLUMNS
Where Table_Name = #TableName
) As TheRow
Where RowNum = #index
--Finishes Closes each column insert (in every instance)
Set #InsertTableRowName = Case
When #TempFilterType IN('varchar', 'nvarchar','char', 'nchar')
Then #InsertTableRowName + ' + '''''''''
When #TempFilterType IN('datetime', 'date')
Then #InsertTableRowName + ') + '''''''''
Else
#InsertTableRowName + ') '
End
--Links each Row together with commas and plus signs until the very end.
If #index < #rowcount
Begin
Set #InsertTableRowName = Case
When #TempFilterType IN('varchar', 'nvarchar','char', 'nchar')
Then #InsertTableRowName + ' + ' + ''',''' + ' + '
When #TempFilterType IN('datetime', 'date')
Then #InsertTableRowName + ' + '','' + '
Else
#InsertTableRowName + ' + '','' + '
End
End
Set #index = #index + 1
End
--Puts the Query together (without any of the Parameters yet).
--First, determine if a new table should be used instead.
If #NewTableName = ''
Begin
Set #NewTableName = #TableName
End
--Next, Build the Query, and do it accordingly with if there is a Find/Replace asked for.
Set #execFunction = 'Select '
If #VarCharFind <> ''
Begin
Set #execFunction = #execFunction + 'Replace('
End
Set #execFunction = #execFunction + '''insert into ' + #NewTableName + ' Values('' + ' + #InsertTableRowName + ' + '')'' '
If #VarCharFind <> ''
Begin
Set #execFunction = #execFunction + ', ''' + #VarCharFind + ''', ''' + #VarCharReplace + ''') '
End
Set #execFunction = #execFunction + 'From ' + #TableName
--Adds in the optional Parameters
If #OptionalParam <> ''
Begin
Set #execFunction = #execFunction + ' ' + #OptionalParam
End
Set #execFunction = #execFunction + CHAR(13)+CHAR(10)
--Executes the function and pulls an entire set of queries to copy into the new Database
Print #execFunction
Exec(#execFunction)
GO
Related
This question already has answers here:
Find a value anywhere in a database
(18 answers)
Search all tables, all columns for a specific value SQL Server [duplicate]
(4 answers)
Closed 5 years ago.
Suppose I have string to search "Sample String" and I have 100 tables in my database.
I want to search if any of the table contains this string.
Eg. If tlbSample contains string "Sample String" then it should show it.
I tried :-
SELECT name
FROM sys.tables
WHERE name LIKE '%Sample String%'
But no luck.
Please help me.
You can use this. I have copied it from here : https://stackoverflow.com/a/13588431/400447
DECLARE #SearchStrTableName nvarchar(255), #SearchStrColumnName nvarchar(255), #SearchStrColumnValue nvarchar(255), #SearchStrInXML bit, #FullRowResult bit, #FullRowResultRows int
SET #SearchStrColumnValue = '%searchthis%' /* use LIKE syntax */
SET #FullRowResult = 1
SET #FullRowResultRows = 3
SET #SearchStrTableName = NULL /* NULL for all tables, uses LIKE syntax */
SET #SearchStrColumnName = NULL /* NULL for all columns, uses LIKE syntax */
SET #SearchStrInXML = 0 /* Searching XML data may be slow */
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
CREATE TABLE #Results (TableName nvarchar(128), ColumnName nvarchar(128), ColumnValue nvarchar(max),ColumnType nvarchar(20))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256) = '',#ColumnName nvarchar(128),#ColumnType nvarchar(20), #QuotedSearchStrColumnValue nvarchar(110), #QuotedSearchStrColumnName nvarchar(110)
SET #QuotedSearchStrColumnValue = QUOTENAME(#SearchStrColumnValue,'''')
DECLARE #ColumnNameTable TABLE (COLUMN_NAME nvarchar(128),DATA_TYPE nvarchar(20))
WHILE #TableName IS NOT NULL
BEGIN
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME LIKE COALESCE(#SearchStrTableName,TABLE_NAME)
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0
)
IF #TableName IS NOT NULL
BEGIN
DECLARE #sql VARCHAR(MAX)
SET #sql = 'SELECT QUOTENAME(COLUMN_NAME),DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(''' + #TableName + ''', 2)
AND TABLE_NAME = PARSENAME(''' + #TableName + ''', 1)
AND DATA_TYPE IN (' + CASE WHEN ISNUMERIC(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(#SearchStrColumnValue,'%',''),'_',''),'[',''),']',''),'-','')) = 1 THEN '''tinyint'',''int'',''smallint'',''bigint'',''numeric'',''decimal'',''smallmoney'',''money'',' ELSE '' END + '''char'',''varchar'',''nchar'',''nvarchar'',''timestamp'',''uniqueidentifier''' + CASE #SearchStrInXML WHEN 1 THEN ',''xml''' ELSE '' END + ')
AND COLUMN_NAME LIKE COALESCE(' + CASE WHEN #SearchStrColumnName IS NULL THEN 'NULL' ELSE '''' + #SearchStrColumnName + '''' END + ',COLUMN_NAME)'
INSERT INTO #ColumnNameTable
EXEC (#sql)
WHILE EXISTS (SELECT TOP 1 COLUMN_NAME FROM #ColumnNameTable)
BEGIN
PRINT #ColumnName
SELECT TOP 1 #ColumnName = COLUMN_NAME,#ColumnType = DATA_TYPE FROM #ColumnNameTable
SET #sql = 'SELECT ''' + #TableName + ''',''' + #ColumnName + ''',' + CASE #ColumnType WHEN 'xml' THEN 'LEFT(CAST(' + #ColumnName + ' AS nvarchar(MAX)), 4096),'''
WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ #ColumnName + '),'''
ELSE 'LEFT(' + #ColumnName + ', 4096),''' END + #ColumnType + '''
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + CASE #ColumnType WHEN 'xml' THEN 'CAST(' + #ColumnName + ' AS nvarchar(MAX))'
WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ #ColumnName + ')'
ELSE #ColumnName END + ' LIKE ' + #QuotedSearchStrColumnValue
INSERT INTO #Results
EXEC(#sql)
IF ##ROWCOUNT > 0 IF #FullRowResult = 1
BEGIN
SET #sql = 'SELECT TOP ' + CAST(#FullRowResultRows AS VARCHAR(3)) + ' ''' + #TableName + ''' AS [TableFound],''' + #ColumnName + ''' AS [ColumnFound],''FullRow>'' AS [FullRow>],*' +
' FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + CASE #ColumnType WHEN 'xml' THEN 'CAST(' + #ColumnName + ' AS nvarchar(MAX))'
WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ #ColumnName + ')'
ELSE #ColumnName END + ' LIKE ' + #QuotedSearchStrColumnValue
EXEC(#sql)
END
DELETE FROM #ColumnNameTable WHERE COLUMN_NAME = #ColumnName
END
END
END
SET NOCOUNT OFF
SELECT TableName, ColumnName, ColumnValue, ColumnType, COUNT(*) AS Count FROM #Results
GROUP BY TableName, ColumnName, ColumnValue, ColumnType
I need to create a mssql query, in that query i would like to put 8 parameters, they are:
table_primary_key : primary key column name,
table_name : table name,
start_row : starting from this row,
limit_row : end row,
column_name : where column name,
column_value : where column name = column value,
sort_by : sort by column name.
order : ASC / DESC.
note: the bold one is the one i haven't implemented yet.
my current query is this :
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (ORDER BY *sort_by*) as row
FROM *table_name*
) a
WHERE row > *start_row* AND row <= *limit_row*
my question is how I add table_primary_key, column_name, column_value, order to my current query?
my goal is make query display data from a table_name, start from
start_row until limit_row, where column_name = column_value. and the
data will be sort by sort_by and the order is according to order
if my question int clear enough please ask, thanks
You can try to use dynamic sql expression like this:
declare
#table_primary_key varchar(max) = 'ProjectID',
#table_name varchar(max) = 'ProjectList',
#start_row int = 10,
#limit_row int = 20,
#column_name varchar(max) = 'ProjectStatus',
#column_value varchar(max) = '5',
#sort_by varchar(max) = 'ProjectName',
#order varchar(4) = 'ASC' -- 'DESC'
declare
#sql varchar(max) = ''
set #sql = 'SELECT * FROM ( '
+ 'SELECT ' + #table_primary_key + ', ROW_NUMBER() OVER (ORDER BY ' + #sort_by + ' ' + #order + ') as row FROM ' + #table_name + ' WHERE ' + #column_name + ' = ''' + #column_value + ''') a'
+ ' WHERE row > ' + cast(#start_row as varchar) + ' and row <= ' + cast(#limit_row as varchar)
exec ( #sql )
Or you can use stored procedure
create procedure dbo.GetResults
(
#table_primary_key varchar(max),
#table_name varchar(max),
#start_row int,
#limit_row int,
#column_name varchar(max),
#column_value varchar(max),
#sort_by varchar(max),
#order varchar(4)
)
as
begin
declare
#sql varchar(max) = ''
set #sql = 'SELECT * FROM ( '
+ 'SELECT ' + #table_primary_key + ', ROW_NUMBER() OVER (ORDER BY ' + #sort_by + ' ' + #order + ') as row FROM ' + #table_name + ' WHERE ' + #column_name + ' = ''' + #column_value + ''') a'
+ ' WHERE row > ' + cast(#start_row as varchar) + ' and row <= ' + cast(#limit_row as varchar)
exec ( #sql )
end
and then...
exec GetResults 'ProjectID', 'ProjectList', 10, 20, 'ProjectStatus', '5', 'ProjectName', 'ASC'
I have wide table with 100 columns.
I need a SP which takes 100 parameters and then does the insert.
I know how to do this manually. But having the table definition and knowing that SP parameters will have exact same name of the table columns, can you think of a better/faster way to generate this stored procedure?
I use SQL to write it for you. Check it out and let me know if it needs any tweaks or if you have any questions.
IF OBJECT_ID('yourTable') IS NOT NULL
DROP TABLE yourTable;
CREATE TABLE yourTable
(
col1 INT,
col2 VARCHAR(100),
col3 NUMERIC(18,2)
)
DECLARE #InputParams VARCHAR(MAX),
#InsertColumns VARCHAR(MAX),
#InsertParams VARCHAR(MAX);
WITH CTE_columns
AS
(
SELECT COLUMN_NAME,
UPPER(DATA_TYPE) data_type,
'(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) + ')' max_length,
CASE
WHEN DATA_TYPE IN ('Numeric','Decimal') THEN CONCAT('(',NUMERIC_PRECISION,',',NUMERIC_SCALE,')')
END prec_scale
--#InsertColumns = COALESCE(#InsertColumns + ',','') + COLUMN_NAME,
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE TABLE_NAME = 'yourTable'
)
SELECT #InputParams = COALESCE(#InputParams + ',','') + CONCAT('#',column_name,' ',data_type,max_length,prec_scale),
#InsertColumns = COALESCE(#InsertColumns + ',','') + COLUMN_NAME,
#InsertParams = COALESCE(#InsertParams + ',','') + '#'+ COLUMN_NAME
FROM CTE_columns
SELECT
'CREATE PROCEDURE dbo.yourProc ' + #InputParams +
' AS
INSERT INTO yourTable(' + #InsertColumns + ')
VALUES (' + #InsertParams + ');
GO'
Results(Formatting isn't great, but it works):
CREATE PROCEDURE dbo.yourProc #col1 INT,#col2 VARCHAR(100),#col3 NUMERIC(18,2) AS
INSERT INTO yourTable(col1,col2,col3)
VALUES (#col1,#col2,#col3);
GO
For this type of scenario, I like to leverage table types.
First, create the table type:
CREATE TYPE [YourType] AS TABLE (columns...)
In C#, populate a DataTable "template" by running this query (using a DataAdapter):
DECLARE #tt AS [YourType]
SELECT * FROM #tt
Then add a row to the table and cycle through the columns to add the necessary values.
Then pass the datatable as a parameter into your procedure:
CREATE PROCEDURE [YourProc]
#tt [YourType] READONLY
AS
BEGIN
--do stuff
END
An added benefit of this approach is that you can pass multiple records into the procedure with a single call.
You can probably quickly modify this for your needs:
Declare #tableName nvarchar(100) = 'aspnet_Membership'
Declare #objectName nvarchar(100) = 'Membership'
DECLARE #newLineChar AS CHAR(2) = CHAR(13) + CHAR(10)
Declare #columnName nvarchar(50)
Declare #dataType nvarchar(50)
Declare #characterLength int
Declare #isNullableString varchar(3)
Declare #ordinalPosition int
Declare #firstSortOrder smallint
Declare #variableTableCreateCode nvarchar(max) = ''
Declare #variableTableDataTypeCode nvarchar(128)
Declare #variableTableSelectCode001 nvarchar(max) = ''
Declare #variableTableSelectCode002 nvarchar(max) = ''
Declare #varableTableInsertIntoCode nvarchar(max) = ''
Declare tbl_ColumnCursor Cursor For
Select colSchema.COLUMN_NAME, colSchema.DATA_TYPE, colSchema.CHARACTER_MAXIMUM_LENGTH, colSchema.IS_NULLABLE , colSchema.ORDINAL_POSITION , FirstSortOrder = CASE WHEN PrimaryKeyDerived.CONSTRAINT_TYPE IS NOT NULL THEN 1 ELSE 2 END
from INFORMATION_SCHEMA.COLUMNS colSchema
LEFT JOIN
(
SELECT
INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
,INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME
,INFORMATION_SCHEMA.TABLE_CONSTRAINTS.CONSTRAINT_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
LEFT OUTER JOIN information_schema.KEY_COLUMN_USAGE
ON
INFORMATION_SCHEMA.COLUMNS.TABLE_NAME=information_schema.KEY_COLUMN_USAGE.TABLE_NAME
AND INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME=information_schema.KEY_COLUMN_USAGE.COLUMN_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS
ON
information_schema.KEY_COLUMN_USAGE.TABLE_NAME=information_schema.TABLE_CONSTRAINTS.TABLE_NAME
AND information_schema.KEY_COLUMN_USAGE.CONSTRAINT_NAME=information_schema.TABLE_CONSTRAINTS.CONSTRAINT_NAME
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
) as PrimaryKeyDerived on colSchema.TABLE_NAME = PrimaryKeyDerived.TABLE_NAME and colSchema.COLUMN_NAME = PrimaryKeyDerived.COLUMN_NAME
where colSchema.TABLE_NAME = #tableName
Order By FirstSortOrder , colSchema.ORDINAL_POSITION
Set #variableTableCreateCode = 'declare #' + #objectName + 'Holder table ( ' + #objectName + 'SurrogateKey int , '
Set #variableTableSelectCode001 = 'INSERT INTO #' + #objectName + 'Holder ( '
Set #variableTableSelectCode002 = ' SELECT '
Set #varableTableInsertIntoCode = 'INSERT INTO '+#tableName+' ( '
Open tbl_ColumnCursor
Fetch Next From tbl_ColumnCursor Into #ColumnName, #dataType, #characterLength, #isNullableString, #ordinalPosition , #firstSortOrder
While ##FETCH_STATUS = 0
Begin
print '/#ColumnName/'
print #ColumnName
print ''
print '/##dataType/'
print #dataType
print ''
print '/###isNullableString/'
print #isNullableString
print ''
Select #variableTableDataTypeCode =
case
when #dataType like '%char%' and #characterLength = -1 Then
#dataType+'(max)'
when #dataType like '%char%' and #characterLength = 1 Then
#dataType+'('+convert(varchar(32), #characterLength)+')'
When (#dataType like '%char%') Or (#dataType = 'xml') Or (#dataType like '%text%') Then
#dataType+'('+convert(varchar(32), #characterLength)+')'
Else #dataType
End
Set #variableTableCreateCode = #variableTableCreateCode + ' [' + #columnName + '] ' + #variableTableDataTypeCode +','
select #variableTableSelectCode002 = #variableTableSelectCode002 + 'T.MyEntity.value(''#' + #columnName + ''', '''+#variableTableDataTypeCode+''') AS ' + #columnName + ','
Fetch Next From tbl_ColumnCursor Into #ColumnName, #dataType, #characterLength , #isNullableString , #ordinalPosition , #firstSortOrder
End
Close tbl_ColumnCursor
Deallocate tbl_ColumnCursor
if(DATALENGTH(#variableTableCreateCode) > 0)
BEGIN
select #variableTableCreateCode = LEFT(#variableTableCreateCode, LEN(#variableTableCreateCode) -1)
END
if(DATALENGTH(#variableTableSelectCode002) > 0)
BEGIN
select #variableTableSelectCode002 = LEFT(#variableTableSelectCode002, LEN(#variableTableSelectCode002) -1)
END
Set #variableTableCreateCode = #variableTableCreateCode + #newLineChar + ' ) '
select #variableTableCreateCode
select #variableTableSelectCode001 = #variableTableSelectCode001 + ( SELECT
MyColumns = STUFF
(
(
SELECT ', [' + r.COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.COLUMNS AS r
WHERE r.TABLE_NAME = tabs.TABLE_NAME
ORDER BY r.ORDINAL_POSITION
FOR XML PATH(''), TYPE
).value('.[1]','nvarchar(max)'),
1,1,''
)
FROM INFORMATION_SCHEMA.TABLES AS tabs
/* Optional WHERE Clause */
WHERE
tabs.TABLE_NAME = #tableName
)
select #variableTableSelectCode001 = #variableTableSelectCode001 + ' ) '+#newLineChar
select #variableTableSelectCode002 = #variableTableSelectCode002 + ' FROM #xmldata.nodes(''RootElement/' + #tableName + 'Elements/' + #tableName + 'Element'') AS T(MyEntity); '
select #variableTableSelectCode001 + #variableTableSelectCode002
select #varableTableInsertIntoCode = #varableTableInsertIntoCode + ( SELECT
MyColumns = STUFF
(
(
SELECT ', [' + r.COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.COLUMNS AS r
WHERE r.TABLE_NAME = tabs.TABLE_NAME
ORDER BY r.ORDINAL_POSITION
FOR XML PATH(''), TYPE
).value('.[1]','nvarchar(max)'),
1,1,''
)
FROM INFORMATION_SCHEMA.TABLES AS tabs
WHERE
tabs.TABLE_NAME = #tableName
)
select #varableTableInsertIntoCode = #varableTableInsertIntoCode + ' ) SELECT '
select #varableTableInsertIntoCode = #varableTableInsertIntoCode + ( SELECT
MyColumns = STUFF
(
(
SELECT ', holder.[' + r.COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.COLUMNS AS r
WHERE r.TABLE_NAME = tabs.TABLE_NAME
ORDER BY r.ORDINAL_POSITION
FOR XML PATH(''), TYPE
).value('.[1]','nvarchar(max)'),
1,1,''
)
FROM INFORMATION_SCHEMA.TABLES AS tabs
WHERE
tabs.TABLE_NAME = #tableName
)
select #varableTableInsertIntoCode = #varableTableInsertIntoCode + ' from #' + #objectName + 'Holder holder where not exists ( select null from ' +#tableName+ ' realTable where realTable.Name = holder.Name and realTable.IsDeleted = holder.IsDeleted ) '
select #varableTableInsertIntoCode
SELECT
tabs.TABLE_NAME,
MyColumns = STUFF
(
(
SELECT ', alias.[' + r.COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.COLUMNS AS r
WHERE r.TABLE_NAME = tabs.TABLE_NAME
ORDER BY r.ORDINAL_POSITION
FOR XML PATH(''), TYPE
).value('.[1]','nvarchar(max)'),
1,1,''
)
FROM INFORMATION_SCHEMA.TABLES AS tabs
/* Optional WHERE Clause */
WHERE
tabs.TABLE_NAME = #tableName
ORDER BY tabs.TABLE_NAME;
So, I've been hunting for a solution for this for awhile and have come up with what sort of works ... but I can't help feeling that there must be something more elegant.
What I'm looking for is to be able to extract existing data from a populated database & incorporate that data into loading scripts. The database schema & configuration data will be rolled out multiple times, and will change as development continues, so it's important to be able to rebuild the configuration data from existing data, rather than from static data kept in scripts.
Here's what I've cobbled together:
create procedure #dump (
#TableName varchar(128)
)
as
set nocount on
set rowcount 0
declare #template varchar(max)
set #template = 'SET IDENTITY_INSERT [dbo].[' + #TableName + '] ON
MERGE INTO [dbo].[' + #TableName + '] AS [Target]
USING
(
VALUES
{vals}
)
AS [Source] ({fields})
ON [Target].[{pk}] = [Source].[{pk}]
WHEN MATCHED THEN UPDATE SET
{upds}
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
{fields}
)
VALUES
(
{fields}
);
SET IDENTITY_INSERT [dbo].[' + #TableName + '] OFF
--------------------------------------------------
'
declare #pk varchar(max) = ''
declare #vals varchar(max) = '/*
set concat_null_yields_null off
select ''' + '(' + ''' + replace(replace({casts} + '') ,'', '',,'', '', null,''), ''' + ',)' + ''', ''' + ',null)' + ''') from [' + #TableName + ']
*/'
declare #casts varchar(max) = ''
declare #fields varchar(max) = ''
declare #upds varchar(max) = ''
declare #inserts varchar(max) = ''
set #pk = SUBSTRING(#TableName, 1, len(#TableName) - 1) + 'ID'
declare cur_flds
cursor for select c.name, c.type
from syscolumns c
where c.id = object_id(#TableName)
order by c.colid
declare #fn varchar(max)
declare #ft int
open cur_flds
fetch next from cur_flds into #fn, #ft
while ##FETCH_STATUS = 0
begin
if len(#fields) > 0
set #fields = #fields + ', '
set #fields = #fields + '[' + #fn + ']'
if len(#casts) > 0
set #casts = #casts + ' + ' + ''','' + '
if #ft in(56,55,50,38,48)
set #casts = #casts + 'cast([' + #fn + '] as varchar)'
else if #ft = 111
set #casts = #casts + ''''''''' + ' + 'cast([' + #fn + '] as varchar) + ' + ''''''''''
else
set #casts = #casts + ''''''''' + ' + 'replace([' + #fn + '], ''''''''' + ', ' + ''''''''''''') + '''''''''
if #fn != #pk
begin
if len(#upds) > 0
set #upds = #upds + ', '
set #upds = #upds + '[Target].[' + #fn + '] = [Source].[' + #fn + ']'
end
fetch next from cur_flds into #fn, #ft
end
close cur_flds
deallocate cur_flds
set #vals = REPLACE(#vals, '{casts}', #casts)
set #template = REPLACE(#template, '{pk}', #pk)
set #template = REPLACE(#template, '{vals}', #vals)
set #template = REPLACE(#template, '{fields}', #fields)
set #template = REPLACE(#template, '{upds}', #upds)
set #template = REPLACE(#template, '{inserts}', #inserts)
print #template
go
exec #dump 'ActionItemSystems'
drop proc #dump
That ends up giving me output of:
SET IDENTITY_INSERT [dbo].[ActionItemSystems] ON
MERGE INTO [dbo].[ActionItemSystems] AS [Target]
USING
(
VALUES
/*
set concat_null_yields_null off
select '(' + replace(replace(cast([ActionItemSystemID] as varchar) + ',' + '''' + replace([ActionItemSystemName], '''', '''''') + '''' + ') ,', ',,', ', null,'), ',)', ',null)') from [ActionItemSystems]
*/
)
AS [Source] ([ActionItemSystemID], [ActionItemSystemName])
ON [Target].[ActionItemSystemID] = [Source].[ActionItemSystemID]
WHEN MATCHED THEN UPDATE SET
[Target].[ActionItemSystemName] = [Source].[ActionItemSystemName]
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
[ActionItemSystemID], [ActionItemSystemName]
)
VALUES
(
[ActionItemSystemID], [ActionItemSystemName]
);
SET IDENTITY_INSERT [dbo].[ActionItemSystems] OFF
From this point, I can take the commented-out bit
set concat_null_yields_null off
select '(' + replace(replace(cast([ActionItemSystemID] as varchar) + ',' + '''' + replace([ActionItemSystemName], '''', '''''') + '''' + ') ,', ',,', ', null,'), ',)', ',null)') from [ActionItemSystems]
execute that, and get output like:
(33,'7111-5 -Upstream/Seed Lab') ,
(32,'7301-Seed Lab') ,
(30,'7807 UFDF') ,
(14,'BAS Panel Upgrade') ,
(1,'Clean Steam') ,
(13,'DCS') ,
(2,'HWFI') ,
(3,'MCS') ,
(12,'MES') ,
(31,'Seed Lab') ,
(18,'UCS WRO') ,
(34,'Upstream Seed Lab') ,
(29,'Viral Filtration') ,
which can then be incorporated (sans the final comma) into the script.
Now, this solution functions, but it's fragile. It depends on various assumptions (e.g., that the Table Name will have a Primary Key of Table Name - trailing 's' and plus ID) that may not hold true for every solution. It also requires cutting & pasting, and rerunning from the start when the table structures change.
This is probably quite a lot of background ... which I'm partly sharing because I couldn't find anything similar out there & thought that somebody might benefit from this. However, I still come back to my real question, which is to say: where's the tool to generate this kind of script for VS Database Projects? There really should be something - something that would take into account whatever the primary key is, that would generate the thing entire, etc.
You can try with this procedure for generating MERGE statements:
https://github.com/readyroll/generate-sql-merge
It is more advanced version of what you already have.
I have a lookup table with about 10 records, I know I can script the structure to a text file, but how can I script the data to insert into commands?
Ten records, and it's urgent?
Just type it out manually. Should be pretty easy to cut-n-paste.
Assuming SQL Server...
SQL Management Studio will generate an insert script. Right-click your database and select Tasks-Export data
This depends pretty much on the tools you are using...
The quick and dirty way is to run a select into a string and tell sql enterprise manager to give you text (not grid) as the output
SELECT 'INSERT INTO TABLES (fields here) VALUES (' + field1 + ', '....
Do something like this:
select "insert into my_targ_table(my_field_1, my_field_2, ..., my_field_n) values(" || x.my_field_1_col || ", " || x.my_field_2_col || ");"
from my_source_table x
Then just run the script you've generated.
This code works with all tables
DECLARE #TblName varchar(128)
DECLARE #WhereClause varchar(255)
DECLARE #cmd1 varchar(7000)
DECLARE #cmd2 varchar(7000)
SET #TblName = '<tablename>' --Name of your table
SET #WhereClause = ' ' --where clause ex columnA = 1
SET #cmd1 = 'SELECT '' INSERT INTO ' + #TblName + ' ( '
SET #cmd2 = ' + '' VALUES ( '' + '
create table #tableDef (id int identity (1,1), ColType int, ColName varchar(128))
--Fetch column names and datatypes
insert #tableDef (ColType, ColName)
select case when DATA_TYPE like '%char%' then 1
when DATA_TYPE like '%datetime%' then 2
else 0 end ,
COLUMN_NAME
from information_schema.columns
where TABLE_NAME = #TblName
order by ORDINAL_POSITION
SELECT #cmd1 = #cmd1 + ColName + ',',
#cmd2 = #cmd2
+ ' CASE WHEN ' + ColName + ' IS NULL '
+ ' THEN ''NULL'' '
+ ' ELSE '
+ case ColType
when 1 then ''''''''' + ' + ColName + ' + '''''''''
when 2 then ''''''''' + ' + 'CONVERT(VARCHAR(20),' + ColName + ')' + ' + '''''''''
else 'CONVERT(VARCHAR(20),' + ColName + ')' end
+ ' END + '','' + '
from #tableDef
order by id
select #cmd1 = left(#cmd1,len(#cmd1)-1) + ' ) '' '
select #cmd2 = left(#cmd2,len(#cmd2)-8) + '+'')'' FROM ' + #tblName + #WhereClause
select '/*' + #cmd1 + #cmd2 + '*/'
exec (#cmd1 + #cmd2)
drop table #tableDef