Information_schema.columns in the query - sql

I need to pull the data from custom columns in all tables which have "custom1, custom2, custom3....." columns.
Declare #TableName varchar(max)
set #TableName = 'RandomTable';
with main as
(
select distinct
infos.COLUMN_NAME, infos.TABLE_NAME
from
INFORMATION_SCHEMA.COLUMNS infos
where
infos.TABLE_NAME = #TableName
and infos.COLUMN_NAME like 'Custom%%'
)
This query returns the list of custom columns in any table I specify in the parameter. Any idea how to use that in the query so I can get all the data from the RandomTable.Custom%% columns?
Any idea? I'm loosing the plot on it.

Following incomudro idea and guessing you are using SQL Server you could do something like this:
DECLARE
#TableName VARCHAR(MAX)
,#ColumnName VARCHAR(MAX)
,#SQLQuery VARCHAR(MAX)
,#FirstFlag BIT
SET #TableName = 'TEST'
SELECT
COL.COLUMN_NAME
INTO ##CUSTOM_COL
FROM INFORMATION_SCHEMA.COLUMNS COL
WHERE 1 = 1
AND COLUMN_NAME LIKE 'CUSTOM__'
AND TABLE_NAME = #TableName
DECLARE CUR_CUSTOM_COL CURSOR FOR
SELECT * FROM ##CUSTOM_COL
OPEN CUR_CUSTOM_COL
FETCH NEXT FROM CUR_CUSTOM_COL INTO #ColumnName
SET #FirstFlag = 1
SET #SQLQuery = 'SELECT *'
WHILE ##FETCH_STATUS = 0
BEGIN
IF #FirstFlag = 0
BEGIN
SET #SQLQuery = #SQLQuery + ', '
END
SET #SQLQuery = #SQLQuery + #ColumnName
SET #FirstFlag = 0
FETCH NEXT FROM CUR_CUSTOM_COL INTO #ColumnName
END
CLOSE CUR_CUSTOM_COL
DEALLOCATE CUR_CUSTOM_COL
SET #SQLQuery = #SQLQuery + ' FROM ' + #TableName
EXEC(#SQLQuery)
I saved my workspace in this fiddle. Unfortunaly it doesnt work there as intendet, but it should in your SQL Client(or I did a little typing mistake). With some little modifications you could not only display the custom columns from 1 specified table but from all tables. Also you could, besides selecting it, insert the ouput from the custom columns in temp tables.

Related

Update null value to a column in dynamic SQL

I need to update a specific set of columns with null value, but when I'm trying to pass null value to dynamic SQL I'm not getting any error or output.
DECLARE #Value VARCHAR(100)
SELECT #Value = null
DECLARE #TableName VARCHAR(1000),#ColumnName VARCHAR(100)
DECLARE #Sql NVARCHAR(MAX)
SET #Sql= N''
DECLARE UpdatePlantId_Crsr CURSOR
STATIC FOR
SELECT ST.name AS TableName,SC.name AS ColumnName
FROM
sys.columns SC
INNER JOIN
sys.tables ST ON ST.object_Id = SC.Object_Id
WHERE
SC.name like '%_MLP'
--AND ST.name not like 'tPlant'
OPEN UpdatePlantId_Crsr
IF ##CURSOR_ROWS > 0
BEGIN
FETCH NEXT FROM UpdatePlantId_Crsr INTO #TableName,#ColumnName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #Sql= N''
SELECT #Sql = #Sql + N' UPDATE '+#TableName +' SET '+#ColumnName+ '= '+ #Value +'
'
PRINT #Sql
--EXEC(#Sql)
FETCH NEXT FROM UpdatePlantId_Crsr INTO #TableName,#ColumnName
END
END
CLOSE UpdatePlantId_Crsr
DEALLOCATE UpdatePlantId_Crsr
I suspect that something is wrong with your application if you need to use dynamic SQL to set tables and columns to NULL. That said, the question can still be answered.
You should use sp_executesql. But given that the table and column names cannot be passed in, just set up the SQL correctly:
SET #Sql = N'UPDATE ' + #TableName + ' SET ' + #ColumnName + ' = NULL' ;
EXEC sp_executesql #sql; -- yuo can still use it with no parameters
I am not sure why you are concatenating the #sql string, so I removed that.
Note that + NULL returns NULL -- both for string concatenation and addition.

where clause to search values from multiple column in sql server

I have the sql server table with 51 columns like below
id
remarks1
remarks2
.
.
.
remarks50
I need to search if particular string is present in atleast one remarks field like in the example below
id remarks1 remarks2 remarks3 remarks4
1 key nonkey grabaze jjjjj
2 uuu 888 8888 kkk
3 888 key hjhj kjkj
suppose i need to search key which is present in either remarks1,2,3.....or 50
I can have sql like
select id from tbl where remarks1 ='key' or remarks2='key' and so on ..
writing or query upto 50 columns is really unpractical.. do we have any quick method?
You can try using below stored procedure .
CREATE PROCEDURE sp_FindStringInTable #stringToFind VARCHAR(100), #schema sysname, #table sysname
AS
DECLARE #sqlCommand VARCHAR(8000)
DECLARE #where VARCHAR(8000)
DECLARE #columnName sysname
DECLARE #cursor VARCHAR(8000)
BEGIN TRY
SET #sqlCommand = 'SELECT * FROM [' + #schema + '].[' + #table + '] WHERE'
SET #where = ''
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 (''char'',''nchar'',''ntext'',''nvarchar'',''text'',''varchar'')'
EXEC (#cursor)
OPEN col_cursor
FETCH NEXT FROM col_cursor INTO #columnName
WHILE ##FETCH_STATUS = 0
BEGIN
IF #where <> ''
SET #where = #where + ' OR'
SET #where = #where + ' [' + #columnName + '] LIKE ''' + #stringToFind + ''''
FETCH NEXT FROM col_cursor INTO #columnName
END
CLOSE col_cursor
DEALLOCATE col_cursor
SET #sqlCommand = #sqlCommand + #where
--PRINT #sqlCommand
EXEC (#sqlCommand)
END TRY
BEGIN CATCH
PRINT 'There was an error. Check to make sure object exists.'
IF CURSOR_STATUS('variable', 'col_cursor') <> -3
BEGIN
CLOSE col_cursor
DEALLOCATE col_cursor
END
END CATCH
The stored procedure gets created in the master database so you can use it in any of your databases and it takes three parameters:
stringToFind - this is the string you are looking for. This could be a simple value as 'test' or you can also use the % wildcard such as '%test%', '%test' or 'test%'.
schema - this is the schema owner of the object
table - this is the table name you want to search, the procedure will search all char, nchar, ntext, nvarchar, text and varchar columns in the table
Source
You can use an unpivot to transpose the remarks* columns as rows with a common column name, which you can then filter on. (You'll need to repeat all 51 columns).
Distinct will be needed to eliminate cases where more than one column matches (i.e. to mimic the original or)
SELECT DISTINCT ID, Rmk
FROM
(SELECT ID, Remarks1, Remarks2, Remarks3, Remarks4
FROM Remarks) r
UNPIVOT
(Rmk FOR RmkCol IN (Remarks1, Remarks2, Remarks3, Remarks4))AS unpvt
WHERE rmk = 'key';
Sql Fiddle here
However I would advise you to reconsider normalising this into a 1 to many Remarks table - if your table is large, you will need a large number of indexes on the Remark* columns.
SELECT remarks1, remarks2, remarks3, remarks4 from tabl_name
WHERE CONTAINS (( remarks1, remarks2, remarks3, remarks4),'888') ORDER BY id;

I have the same column in multiple tables, and want to update that column in all tables to a specific value. How can I do this?

The column is "CreatedDateTime" which is pretty self-explanatory. It tracks whatever time the record was commited. I need to update this value in over 100 tables and would rather have a cool SQL trick to do it in a couple lines rather than copy pasting 100 lines with the only difference being the table name.
Any help would be appreciated, having a hard time finding anything on updating columns across tables (which is weird and probably bad practice anyways, and I'm sorry for that).
Thanks!
EDIT: This post showed me how to get all the tables that have the column
I want to show all tables that have specified column name
if that's any help. It's a start for me anyways.
If that's a one time task, just run this query, copy & paste the result to query window and run it
Select 'UPDATE ' + TABLE_NAME + ' SET CreatedDateTime = ''<<New Value>>'' '
From INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'CreatedDateTime'
You could try using a cursor : like this
declare cur cursor for Select Table_Name From INFORMATION_SCHEMA.COLUMNS Where column_name = 'CreatedDateTime'
declare #tablename nvarchar(max)
declare #sqlstring nvarchar(max)
open cur
fetch next from cur into #tablename
while ##fetch_status=0
begin
--print #tablename
set #sqlstring = 'update ' + #tablename + ' set CreatedDateTime = getdate()'
exec sp_executesql #sqlstring
fetch next from cur into #tablename
end
close cur
deallocate cur
You can use the Information_Schema.Columns to build update scripts for you.
Declare #ColName as nVarchar(100), #NewValue as nVarchar(50)
Set #ColName = 'Modified' -- 'your col name'
Set #NewValue = '2013-11-04 15:22:31' -- your date time value
Select 'Update ' + TABLE_NAME + ' set ' + COLUMN_NAME + ' = ''' + #NewValue + '''' From INFORMATION_SCHEMA.COLUMNS Where column_name = 'modified'

INSERT INTO command doesn't work

I have one outer cursor and one inner cursor also have two tables to work with. Now with the outer cursor i'm making new columns in the table 1 and naming them by the values from the table two, and that works just fine. Problem is with the inner cursor witch i used to insert the values into those new columns from one specific column from another table. This seams not to work, but what confusing me is that i do not get any error messages. Now i hope you understand what i'm trying to do, here is the code so comment for more description about the problem :
DECLARE #rbr_param nvarchar(255)
DECLARE #vrednost nvarchar(255)
DECLARE #cName nvarchar(255)
DECLARE #sql nvarchar (255)
DECLARE curs CURSOR FOR SELECT DISTINCT rbr_param FROM dbo.parametri_pomocna ORDER BY rbr_param
OPEN curs
FETCH NEXT FROM curs
INTO #rbr_param
WHILE ##FETCH_STATUS = 0
BEGIN
SET #cName = 'P_'+#rbr_param+'_P'
EXEC('ALTER TABLE dbo.Parametri ADD ' + #cName + ' nvarchar(255)')
DECLARE vrd CURSOR FOR SELECT DISTINCT vrednost FROM dbo.parametri_pomocna
OPEN vrd
FETCH NEXT FROM vrd
INTO #vrednost
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = 'INSERT INTO dbo.Parametri'+(#cName)+ ' SELECT vrednost FROM dbo.parametri_pomocna WHERE vrednost = '+#vrednost+ ' AND rbr_param = '+#rbr_param
if exists (select * from INFORMATION_SCHEMA.COLUMNS where table_name = 'dbo.Parametri' and column_name = '#cName')
begin
exec(#sql)
end
FETCH NEXT FROM vrd
INTO #vrednost
END --end vrd
CLOSE vrd
DEALLOCATE vrd
FETCH NEXT FROM curs
INTO #rbr_param
END
CLOSE curs
DEALLOCATE curs
You have two problems here:
if exists ( select * from INFORMATION_SCHEMA.COLUMNS
where table_name = 'dbo.Parametri'
and column_name = '#cName'
)
(1) This view will never have table_name = schema name and table name.
(2) You have enclosed your variable name in single quotes for some reason.
For both of these reasons, your IF condition will never return true.
Try:
IF EXISTS
(
SELECT 1 FROM sys.columns
WHERE [object_id] = OBJECT_ID('dbo.Parametri')
AND name = #cName
)
(And here is why I prefer catalog views over INFORMATION_SCHEMA.)
Also this double-nested cursor thing seems quite inefficient and a lot more code than necessary to achieve what I think you're trying to do. How about something like this instead:
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + N'ALTER TABLE dbo.Parametri ADD '
+ QUOTENAME('P_' + rbr_param + '_P') + ' NVARCHAR(255);'
FROM dbo.parametri_pomocna GROUP BY rbr_param;
EXEC sp_executesql #sql;
SET #sql = N'';
SELECT #sql = #sql + N'INSERT dbo.Parametri('+QUOTENAME('P_' + rbr_param + '_P')+ ')
SELECT vrednost
FROM dbo.parametri_pomocna WHERE rbr_param = ''' + rbr_param + '''
GROUP BY vrednost;'
FROM dbo.parametri_pomocna
GROUP BY rbr_param;
EXEC sp_executesql #sql;

SQL query shorthand for not selecting null columns when doing select all

when I do:
SELECT *
FROM SOMETABLE
I get all the columns from SOMETABLE, but I DON'T want the columns which are NULL (for all records). How do I do this?
Reason: this table has 20 columns, 10 of these are set but 10 of them are null for certain queries. And it is time consuming to type the columnnames....
Thanks,
Voodoo
SQL supports the * wildcard which means all columns. There is no wildcard for all columns except the ones you don't want.
Type out the column names. It can't be more work than asking questions on Stack Overflow. Also, copy & paste is your friend.
Another suggestion is to define a view that selects the columns you want, and then subsequently you can select * from the view any time you want.
It's possible to do, but kind of complicated. You can retrieve the list of columns in a table from INFORMATION_SCHEMA.COLUMNS. For each column, you can run a query to see if any non-null row exists. Finally, you can run a query based on the resulting column list.
Here's one way to do that, with a cursor:
declare #table_name varchar(256)
set #table_name = 'Airports'
declare #rc int
declare #query nvarchar(max)
declare #column_list varchar(256)
declare columns cursor local for select column_name
from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = #table_name
open columns
declare #column_name varchar(256)
fetch next from columns into #column_name
while ##FETCH_STATUS = 0
begin
set #query = 'select #rc = count(*) from ' + #table_name + ' where ' +
#column_name + ' is not null'
exec sp_executesql #query = #query, #params = N'#rc int output',
#rc = #rc output
if #rc > 0
set #column_list = case when #column_list is null then '' else
#column_list + ', ' end + #column_name
fetch next from columns into #column_name
end
close columns
deallocate columns
set #query = 'select ' + #column_list + ' from ' + #table_name
exec sp_executesql #query = #query
This runs on SQL Server. It might be close enough for Sybase. Hopefully, this demonstrates that typing out a column list isn't that bad :-)