Turn dynamic SELECT query into UPDATE stored procedure SQL - sql

I am rather new to this and I am having a hard time into converting the below SQL query into an UPDATE statement for a stored procedure.
SELECT 'select'+
stuff((
SELECT ',' + 'dbo.' + Function_Name + '(' + Parameters_List + ')' FROM
[SPECIFIC_DATABASE]..Specific_table c WHERE c.Table_Name = t.Table_Name FOR
XML PATH('')),1,1,'')
+' from [' + Database_Name +'].[dbo].['+Table_Name+'] '
+ 'Where Audit_ID>' + CAST(#Audit_ID as nvarchar(100))
As 'Specific Queries'
FROM (SELECT Distinct Database_Name, Table_Name FROM [SPECIFIC_DATABASE]..Specific_table) t
The UPDATE query should be something like
UPDATE Table_name
SET Column_name = Function_Name(Parameters_List)
WHERE Audit_id >= #Audit_ID
FROM [SPECIFIC_DATABASE]..Specific_table
Any suggestions and guidelines on this would be much appreciated!

I think this should give you what you want, but I don't see any any reference to a Column_Name, so I'm assuming you will hardcode that.
select 'UPDATE tbl' + stuff((
select ' set Column_Name = ' + 'dbo.' + Function_Name + '(' + Parameters_List + ')'
from [SPECIFIC_DATABASE]..Specific_table c
where c.Table_Name = t.Table_Name
for xml PATH('')
), 1, 1, '')
+ ' from [' + Database_Name + '].[dbo].[' + Table_Name + '] tbl'
+ 'Where Audit_ID>'
+ CAST(#Audit_ID as nvarchar(100)) as 'Specific Queries'
from (
select distinct Database_Name, Table_Name
from [SPECIFIC_DATABASE]..Specific_table
) t
If the answer's not right then it might be helpful if you post what is the current output of your first query and maybe some more details as to what are the contents of the table called "Specific_table".

Related

sql-query, find and replace with this particular code

I need to understand the following SQL query and would like to ask if anybody could explain it to me a bit more in detail (like the xml path) as well as update it with a replace element?
So I want to find all values with BlaBlaBlaBla and replace them with HaHaHaHa instead. At the moment the query is finding all values of BlaBlaBlaBla only.
DECLARE #searchstring NVARCHAR(255)
SET #searchstring = '%BlaBlaBlaBla%'
DECLARE #sql NVARCHAR(max)
SELECT #sql = STUFF((
SELECT
' UNION ALL SELECT ''' + TABLE_SCHEMA + '.' + TABLE_NAME + ''' AS tbl, ''' + COLUMN_NAME + ''' AS col, [' + COLUMN_NAME + '] AS val' +
' FROM [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] WHERE [' + COLUMN_NAME + '] LIKE ''' + #searchstring + ''''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE in ('nvarchar', 'varchar', 'char', 'ntext') FOR XML PATH('')) ,1, 11, '')
Exec (#sql)
I believe that the XML PATH is a trick to get the strings to all concatenate together.
You could change it to REPLACE with something like this:
SELECT #sql =
SELECT
' UPDATE ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + '
SET ' + QUOTENAME(COLUMN_NAME) + ' = REPLACE(' + QUOTENAME(COLUMN_NAME) + ', ''' + #search_string + ''', ' + ', ''' + #replace_string + '''
WHERE ' + QUOTENAME(COLUMN_NAME) + ' LIKE ''' + #searchstring + ''''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
DATA_TYPE in ('nvarchar', 'varchar', 'char', 'ntext') FOR XML PATH('')
EXEC(#sql)
Some caveats:
I haven't tested this. When you're generating code like this it's very easy to make minor errors with all of the start and end quotes, etc. I would print out the SQL and check it, repeating as necessary until you get the output SQL correct.
Also, this is generally not a good idea. If your database is large and/or has a large number of tables then performance is going to be miserable. You should usually do the analysis of where you think this sort of data is going to appear and write code that will correct it as necessary. The fact that data elements are buried in strings throughout your data is concerning.
Finally, be aware that this might easily update additional data that you didn't intend to update. If you try to update "123" with "456" and there's a string out there that is "My ID is 1234" it's going to become "My ID is 4564".
BTW, the QUOTENAME function is a way of enclosing your table and column names in [ and ], but if the quote character is changed in a DB implementation it should still work.

Create select statement based on INFORMATION_SCHEMA.TABLES

I'm trying to create some overviews and eventually some dynamic select statements for a database.
select 'select ''' + TABLE_SCHEMA + '.' + TABLE_NAME + ''', count(*) from [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] union all'
from INFORMATION_SCHEMA.TABLES
where TABLE_TYPE != 'VIEW'
and (select count(*) from TABLE_SCHEMA.TABLE_NAME) > 0
I'm stuck on this part: select count(*) from TABLE_SCHEMA.TABLE_NAME
Which throws Invalid object name
Is there any way I can make that work dynamically?
If you want to exclude tables with no rows from your result set, add a HAVING COUNT(*) > 0 clause to your generated SQL:
select 'select ''' + TABLE_SCHEMA + '.' + TABLE_NAME + ''', count(*) from [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] having count(*) > 0 union all'
from INFORMATION_SCHEMA.TABLES
where TABLE_TYPE != 'VIEW'

Append Quotes for all VARCHAR Columns when exporting to csv file

I have a stored procedure which when run gives a table output. I want to export this procedure to a csv file but want to append double/single quotes for all the columns with a datatype CHAR/VARCHAR.
For Example:
Stored Proc O/P:
ID Name Address SSN
1 abd 9301,LeeHwy, 22031 64279100
Output in CSV File:
1,"abd","9301,LeeHwy, 22031",64279100
Can anyone also help me on how I can use a BAT file to execute the procedure and generate this csv file.
One way to do this, is to loop through the table schema to extract the varchar columns. I have tested this for one of my tables, and it worked:
DECLARE #tableName VARCHAR(Max) = '[Put your table name here]';
DECLARE #currColumns VARCHAR(Max) = NULL;
SELECT #currColumns = COALESCE(#currColumns + ','
+ CASE WHEN t.Name = 'varchar' THEN '''"'' + ' ELSE '' END
+ '[', '[') + c.name + ']'
+ CASE WHEN t.Name = 'varchar' THEN '+ ''"''' ELSE '' END
+ ' as [' + c.name + ']'
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)
EXEC('SELECT ' + #currColumns + ' FROM ' + #tableName);
It's a quick and dirty way.
UPDATE (comment):
Inserting into a table is really easy. Just do this:
INSERT INTO [TABLE]
EXEC('SELECT ' + #currColumns + ' FROM ' + #tableName);
I have found a solution for my problem.
Credits also go to #Rogala (The developer who gave initial answer to the question) for triggering the idea of using system tables.
The code is as below:
DECLARE #tableName VARCHAR(Max) = '[Put your table name here]';
DECLARE #currColumns VARCHAR(Max) = NULL;
Declare #Delim CHAR(5)='''"''+'
SELECT #currColumns = COALESCE(#currColumns + ','+ CASE WHEN DATA_TYPE= 'varchar' THEN '''"'' + ' ELSE '' END + '[', '[') + COLUMN_NAME + ']'
+ CASE WHEN DATA_TYPE = 'varchar' THEN '+ ''"''' ELSE '' END + ' as [' + COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.Columns
WHERE table_name = #tableName
Set #currColumns= #Delim+#currColumns
EXEC('SELECT ' + #currColumns + ' FROM ' + #tableName);

How to generate create script of table using SQL query in SQL Server

I want to generate create table script of already created table in my live database.
I know we can generate scripts using right click on table and click on 'script table as' menu and script will be generated. Because my live db UI is running very slow.
I want to do same process using SQL query. is there any way??
If you are looking for a TSQL solution, it is quite verbose, as this example shows.
A shorter alternative would be using the SMO library (example)
(I originally answered this here, but SQL Server-only devs probably do not relate the question title to this problem)
For a more complete(-ish) solution for generating a CREATE TABLE statement with indexes, triggers and constraints try the stored procedure made by Lowell Izaguirre.
It has been tested and developed since 2004, last update was in 2013.
I've also made some improvements to include index options (PAD_INDEX, FILLFACTOR, IGNORE_DUP_KEY):
here are the changes, can't fit all the code so you'll find the complete modified version at http://pastebin.com/LXpBeuN1 .
Update
I've talked with Lowell and a new version will be online soon with the new changes for index options and other improvements.
Use this query :
DROP FUNCTION [dbo].[Get_Table_Script]
Go
Create Function Get_Table_Script
(
#vsTableName varchar(50)
)
Returns
VarChar(Max)
With ENCRYPTION
Begin
Declare #ScriptCommand varchar(Max)
Select #ScriptCommand =
' Create Table [' + SO.name + '] (' + o.list + ')'
+
(
Case
When TC.Constraint_Name IS NULL
Then ''
Else 'ALTER TABLE ' + SO.Name + ' ADD CONSTRAINT ' +
TC.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')'
End
)
From sysobjects As SO
Cross Apply
(
Select
' [' + column_name + '] ' +
data_type +
(
Case data_type
When 'sql_variant'
Then ''
When 'text'
Then ''
When 'decimal'
Then '(' + Cast( numeric_precision_radix As varchar ) + ', ' + Cast( numeric_scale As varchar ) + ') '
Else Coalesce( '(' +
Case
When character_maximum_length = -1
Then 'MAX'
Else Cast( character_maximum_length As VarChar )
End + ')' , ''
)
End
)
+ ' ' +
(
Case
When Exists (
Select id
From syscolumns
Where
( object_name(id) = SO.name )
And
( name = column_name )
And
( columnproperty(id,name,'IsIdentity') = 1 )
)
Then 'IDENTITY(' +
Cast( ident_seed(SO.name) As varchar ) + ',' +
Cast( ident_incr(SO.name) As varchar ) + ')'
Else ''
End
) + ' ' +
(
Case
When IS_NULLABLE = 'No'
Then 'NOT '
Else ''
End
) + 'NULL ' +
(
Case
When information_schema.columns.COLUMN_DEFAULT IS NOT NULL
Then 'DEFAULT ' + information_schema.columns.COLUMN_DEFAULT
ELse ''
End
) + ', '
From information_schema.columns
Where
( table_name = SO.name )
Order by ordinal_position
FOR XML PATH('')) o (list)
Inner Join information_schema.table_constraints As TC On (
( TC.Table_name = SO.Name )
AND
( TC.Constraint_Type = 'PRIMARY KEY' )
And
( TC.TABLE_NAME = #vsTableName )
)
Cross Apply
(
Select '[' + Column_Name + '], '
From information_schema.key_column_usage As kcu
Where
( kcu.Constraint_Name = TC.Constraint_Name )
Order By ORDINAL_POSITION
FOR XML PATH('')
) As j (list)
Where
( xtype = 'U' )
AND
( Name NOT IN ('dtproperties') )
Return #ScriptCommand
End
And you can fire this Function like this :
Select [dbo].Get_Table_Script '<Your_Table_Name>'
And for create trigger use this
SELECT
DB_NAME() AS DataBaseName,
dbo.SysObjects.Name AS TriggerName,
dbo.sysComments.Text AS SqlContent
FROM
dbo.SysObjects INNER JOIN
dbo.sysComments ON
dbo.SysObjects.ID = dbo.sysComments.ID
WHERE
(dbo.SysObjects.xType = 'TR')
AND
dbo.SysObjects.Name LIKE '<Trigger_Name>'

check for empty columns

How can I check if any column in a given table only have null or empty string values? Can I in some way extend this for every table in the database?
Here is a stored proc for finding an arbitrary value in the database. It's a fairly small modification to make it search for empty columns.
The procedure generates a list of all the tables and all the columns in the database, and creates a temporary table for storing the results. Then it generates a dynamic SQL and uses the INSERT INTO ... EXEC to fill the result table.
Here's a runnable example off the StackOverflow database:
-- Look for NULLs
DECLARE #sql AS varchar(max)
SELECT #sql = COALESCE(#sql + ' UNION ALL ', '') + sql
FROM (
SELECT 'SELECT ''' + c.TABLE_NAME + '.' + c.COLUMN_NAME + ''' AS COLUMN_NAME, COUNT(NULLIF(' + QUOTENAME(c.COLUMN_NAME) + ', '''')) AS NON_NULL_COUNT, COUNT(*) AS TOTAL_COUNT FROM ' + QUOTENAME(c.TABLE_CATALOG) + '.' + QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME) AS sql
FROM INFORMATION_SCHEMA.COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.TABLES AS t
ON t.TABLE_CATALOG = c.TABLE_CATALOG
AND t.TABLE_SCHEMA = c.TABLE_SCHEMA
AND t.TABLE_NAME = c.TABLE_NAME
WHERE c.DATA_TYPE IN ('nvarchar', 'varchar')
UNION ALL
SELECT 'SELECT ''' + c.TABLE_NAME + '.' + c.COLUMN_NAME + ''' AS COLUMN_NAME, COUNT(' + QUOTENAME(c.COLUMN_NAME) + ') AS NON_NULL_COUNT, COUNT(*) AS TOTAL_COUNT FROM ' + QUOTENAME(c.TABLE_CATALOG) + '.' + QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME) AS sql
FROM INFORMATION_SCHEMA.COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.TABLES AS t
ON t.TABLE_CATALOG = c.TABLE_CATALOG
AND t.TABLE_SCHEMA = c.TABLE_SCHEMA
AND t.TABLE_NAME = c.TABLE_NAME
WHERE c.DATA_TYPE NOT IN ('nvarchar', 'varchar')
AND c.IS_NULLABLE = 'YES'
) AS checks
SET #sql = 'SELECT * FROM (' + #sql + ') AS checks WHERE NON_NULL_COUNT = 0'
EXEC (#sql)
A few things to note:
There are two columns it finds which are completely NULL/blank:
Posts.OwnerDisplayName, Bdges.CreationDate
It converts '' to NULL for nvarchar and varchar columns (if you have char or nchar columns, you would have to change this)
You can't normally put a condition on a query for all columns in a table. You have to pick the columns you want. To get around this you need dynamic sql and the information_schema views.