Search database for all column names with specific values - sql-server

We have a vendor specific application that has 100's of tables and most of them have a column called Company_Code and within that column is stored a value for each company. Is it possible to search the entire database where COMPANY_CODE = 'TST' and return those values?

This should do the trick:
DECLARE #Value varchar(100) = 'TST';
DECLARE #script varchar(1000);
CREATE TABLE ##Results (TableName VARCHAR(100) , ValueCount INT);
DECLARE db_cursor CURSOR FOR
WITH cte AS
(
SELECT o.NAME AS TableName , c.name As ColumnName
FROM sys.sysobjects o
JOIN sys.syscolumns c on o.id = c.id
WHERE c.name = 'COMPANY_CODE '
)
SELECT 'INSERT INTO ##Results (TableName , ValueCount) SELECT ''' + TableName + ''' , COUNT(*) FROM ' + TableName + ' WHERE ' + ColumnName + ' = ''' + #Value + '''' AS Script
FROM cte;
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #script
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #script;
EXEC (#Script);
FETCH NEXT FROM db_cursor INTO #script
END
CLOSE db_cursor
DEALLOCATE db_cursor
SELECT * FROM ##Results WHERE ValueCount > 0

Related

T-SQL search all the columns and the tables from a date value

hi I am trying to search all the columns and tables in a data server that contain a specific date value e.g. '2021-07-22' in SQL server database.
Please notice is NOT a string type, but a datetime type.
I googled and did quite a bit research but could not find anything available. Can anyone provide some help please?
Thanks
DECLARE #SearchDate DATE = '2022-01-01'
DECLARE #SQL NVARCHAR(MAX) = ''
DECLARE #SchemaName SYSNAME
DECLARE #TableName SYSNAME
DECLARE #ColumnName SYSNAME
DECLARE #RowIDName SYSNAME
DECLARE #Results TABLE(ColumnName SYSNAME,RowIDName SYSNAME,RowIDValue NVARCHAR(255), ColumnValue DATETIME)
DECLARE #TableCols CURSOR
SET #TableCols = CURSOR FOR
SELECT QUOTENAME(s.name) AS SchemaName,QUOTENAME(t.name) AS TableName,QUOTENAME(c.name) AS ColumnName,QUOTENAME(Ids.ID) AS RowIDName
FROM sys.tables t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.schemas s ON s.schema_id = t.schema_id
CROSS APPLY (SELECT TYPE_NAME(c.system_type_id))TypeNames(TypeName)
CROSS APPLY (SELECT c2.Name FROM sys.Columns c2 WHERE c2.column_id = 1 AND c2.object_id = c.object_id)IDs(ID)
WHERE t.is_ms_shipped = 0
AND TypeNames.TypeName IN ('date','datetime','datetime2','smalldatetime')
OPEN #TableCols
FETCH NEXT FROM #TableCols INTO #SchemaName,#TableName, #ColumnName,#RowIDName
WHILE ##fetch_status = 0
BEGIN
INSERT INTO #Results(ColumnName,RowIDName,RowIDValue,ColumnValue)
EXEC
(
'SELECT ''' + #SchemaName+'.'+#TableName + '.' + #ColumnName + ''','''+#RowIDName+''','+#RowIDName+' ,' + #ColumnName + '
FROM ' + #TableName +
' WHERE ' + #ColumnName + ' = ''' + #SearchDate+''''
)
FETCH NEXT FROM #TableCols INTO #SchemaName,#TableName, #ColumnName,#RowIDName
END
CLOSE #TableCols
DEALLOCATE #TableCols
SELECT * FROM #Results

Way to select all columns from table and near each one the same column name with prefix?

Let's say I have a table with the following columns:
"col1", "col2", "col3", "new_col1", "new_col2", "new_col3" ...
I want to display the columns in the following way:
select col1, new_col1, col2, new_col2, col3, new_col3 ...
Is there a select command/keyboard shortcut that I can do that without copy each column in the select command
Thank you
I have a custom procedure mapped to Ctrl+8 shortcut.
It's something like that:
CREATE or ALTER PROC dbo.utl_get_select(
#table sysname,
#alias varchar(10) = 'v'
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #query varchar(max) = 'SELECT';
SELECT #alias = ISNULL(#alias, 'v')
SELECT #query = #query + ' ' + #alias + '.' + QUOTENAME(c.name)+','
FROM sys.objects t
JOIN sys.columns c ON c.object_id = t.object_id
WHERE t.name = #table
ORDER BY c.column_id ASC;
SELECT #query = LEFT(#query, LEN(#query)-1) + ' ';
SELECT #query + 'FROM dbo.' + #Table + ' ' + #alias;
END;
We could also use STRING_AGG in SQL Server 2017 or newer.
You can also compare columns names to achieve some customised order.
And the result for EXEC dbo.utl_get_select 'users'
SELECT v.[id], v.[login], v.[email], v.[name], v.[last_name] FROM dbo.users v
Here is a script for Insert and Select
DECLARE #String nvarchar(max)='',#Column nvarchar(100),#Insert nvarchar(max), #Select nvarchar(max),#TBL_NAME nvarchar(150)
SET #TBL_NAME = 'TestTable'
DECLARE CURS CURSOR LOCAL FAST_FORWARD FOR
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TBL_NAME
OPEN CURS
FETCH NEXT FROM CURS INTO #Column
WHILE ##FETCH_STATUS=0
BEGIN
SET #String = #String +'['+#Column+'],'+'['+#Column+'_NEW],'
FETCH NEXT FROM CURS INTO #Column
END
CLOSE CURS
DEALLOCATE CURS
SET #String = SUBSTRING(#String,1,LEN(#String)-1)
SET #Insert = 'INSERT INTO ['+#TBL_NAME+'] ('+#String+')'
SET #Select = 'SELECT '+#String
Select #Insert,#Select

Can you return the results a query from table and Fields returned in a query

The following is the results of a query used to Search Columns
DECLARE #Temp TABLE (
[CoreTable] VARCHAR(250),
[CoreTableDecription] VARCHAR(250),
[FieldName] VARCHAR(250),
[cnt] VARCHAR(250)
)
declare #Keyword1 VARCHAR(100) = '%Prob%'
declare #Keyword2 VARCHAR(100) = '%Prob%'
--------------------------------------------------------------
INSERT INTO #Temp (CoreTable, CoreTableDecription, FieldName, cnt)
VALUES
('PRO','PROTOS_PersonalInformation','AnyCommunicationProblem','1'),
('PRO','PROTOS_PersonalInformation','SightProblems','1'),
('PRO','PROTOS_PersonalInformation','SpeechProblems','1'),
('PRO','PROTOSMODEL_Antenatal_Status','Other_Antenatal_Problems','1'),
('PRO','PROTOSMODEL_Antenatal_Status','Other_Antenatal_Problems_Text','1'),
('PRO','PROTOSMODEL_Baby_Details','Neonatal_medical_problems','1'),
('PRO','PROTOSMODEL_Baby_Details','Neonatal_medical_problems_Text','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected_Bruising','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected_Naevus','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected_Rash','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected_Text','1')
Select * from #Temp
This is great for finding/search and the query used is below
declare #Keyword1 VARCHAR(100) = '%Prob%'
declare #Keyword2 VARCHAR(100) = '%Prob%'
select
LEFT(o.name,3) CoreTable,
o.name CoreTableDesc,
--o.name AS TableName,
c.name AS FieldName
,COUNT(c.name) cnt
from sys.columns c
inner join sys.objects o on c.object_id=o.object_id
where c.name LIKE #Keyword1
and LEFT(o.name,3) in ('PRO')
and c.name LIKE #Keyword2
GROUP BY c.name, LEFT(o.name,3), o.name
-- order by LEFT(o.name,3), c.name
However what I then need to do is run a manual query to determine the values in the columns/tables (see below):
select AnyCommunicationProblem, count(*) cnt
from PROTOS_PersonalInformation
GROUP BY AnyCommunicationProblem
This returns simplythe rows NULL - 2682, No - 87687, Yes - 135478
I'm wondering if there is a way to do this automatically from the results of the first query which display the Table name and Column names
Thanks all the answer was below but I was unsure how to get the count if the data items in
DECLARE
#TABLENAME VARCHAR(255),
#FIELDNAME VARCHAR(255),
#SQL VARCHAR(MAX),
#FieldNamePart1 as varchar(50),
#FieldNamePart2 as varchar(50)
SET #SQL = ''
SET #FieldNamePart1 = 'Type'
SET #FieldNamePart2 = 'Method'
IF #FieldNamepart2 = ''
DECLARE CRS CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE CHARINDEX('PROTOSMODEL',TABLE_NAME) <> 0
AND CHARINDEX(#FieldNamePart1, COLUMN_NAME) <> 0
-- AND CHARINDEX('DATE', COLUMN_NAME) = 0
-- AND CHARINDEX('TIME', COLUMN_NAME) = 0
ELSE
DECLARE CRS CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE CHARINDEX('PROTOSMODEL',TABLE_NAME) <> 0
AND CHARINDEX(#FieldNamePart1, COLUMN_NAME) <> 0
AND CHARINDEX(#FieldNamePart2, COLUMN_NAME) <> 0
-- AND CHARINDEX('DATE', COLUMN_NAME) = 0
-- AND CHARINDEX('TIME', COLUMN_NAME) = 0
OPEN CRS
FETCH NEXT FROM CRS INTO #TABLENAME, #FIELDNAME
WHILE ##FETCH_STATUS = 0
BEGIN
-- SET #SQL = #SQL + CAST('SELECT DISTINCT ''' AS VARCHAR(MAX)) + CAST(#TABLENAME AS VARCHAR(MAX)) + CAST(''' AS PROTOSMODEL_TABLE, ''' AS VARCHAR(MAX)) + CAST(#FIELDNAME AS VARCHAR(MAX)) + CAST(''' AS PROTOSMODEL_FIELD, ' AS VARCHAR(MAX)) + CAST(#FIELDNAME AS VARCHAR(MAX)) + CAST(' AS FIELD_VALUE FROM ' AS VARCHAR(MAX)) + CAST(#TABLENAME AS VARCHAR(MAX)) + CAST(' UNION ALL ' AS VARCHAR(MAX))
SET #SQL = #SQL + 'SELECT DISTINCT ''' + #TABLENAME + ''' AS PROTOSMODEL_TABLE, ''' + #FIELDNAME + ''' AS PROTOSMODEL_FIELD, [' + #FIELDNAME + '] AS FIELD_VALUE FROM ' + #TABLENAME + ' UNION ALL '
FETCH NEXT FROM CRS INTO #TABLENAME, #FIELDNAME
END
CLOSE CRS
DEALLOCATE CRS
SET #SQL = SUBSTRING(#SQL, 1, LEN(#SQL) - 10)
EXEC (#SQL)
GO

SQL Server: Update all null field as 0

I want to update some rows which be include some null fields.
How can I update these rows in SQL Server?
I am asking because a rows has got 180 fields. :)
Please help me.
You can use dynamic SQL to generate a script to run. The following will probably need tweaking for you to exclude columns that you don't want to update etc.
DECLARE #TableName nvarchar(500) = '[dbo].[T]'
DECLARE #DynSql nvarchar(max)
SELECT #DynSql = ISNULL(#DynSql+',','') + QUOTENAME(name) + '= ISNULL(' + QUOTENAME(name) + ',0)'
FROM sys.columns
WHERE object_id = OBJECT_ID(#TableName)
SET #DynSql = 'UPDATE ' + #TableName + 'SET ' + #DynSql
PRINT #DynSql
--EXEC(#DynSql)
I think I understand what you are asking. This will generate an update statement for each column in your table that will set it's value to 0 if it's value is null.
declare #tableName nvarchar(100)
declare #querys varchar(max)
set #querys = ''
set #tableName = 'YOUR TABLE NAME HERE'
select #querys = #querys + 'update ' + #tableName + ' set ' +
QUOTENAME(t.[name]) + '=0 where ' + QUOTENAME(t.[name]) + ' is null;'
from (SELECT [name] FROM syscolumns
WHERE id = (SELECT id
FROM sysobjects
WHERE type = 'U'
AND [NAME] = #tableName))t
select #querys
execute sp_executesql #sqlQuery
Well It is an old post, but I recently had this problem and wanted a dynamic SQL query using the above solution that performed the update depending on column types.
USE [YOUR DATABASE]
DECLARE #tableName nvarchar(100)
DECLARE #name varchar(50)
DECLARE #dtype varchar(50)
DECLARE #CMD NVARCHAR (200)
SET #tableName = [YOUR TABLE NAME]
DECLARE db_cursor CURSOR FOR
SELECT c.name, t.name AS Dtype
FROM sys.columns c
INNER JOIN sys.types t
ON t.system_type_id = c.system_type_id
WHERE c.[object_id] =
(SELECT [object_id] FROM sys.objects WHERE type = 'U' AND [NAME] = #tableName)
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #name, #Dtype
WHILE ##FETCH_STATUS = 0 BEGIN
SET #CMD = 'UPDATE ' + #tableName + ' SET ' + quotename(#name) +' = ' +
(CASE
WHEN (#Dtype = 'bit') THEN '0'
WHEN (#Dtype = 'int') THEN '0'
WHEN (#Dtype = 'decimal') THEN '0'
WHEN (#Dtype = 'date') THEN '''1/1/1900'''
WHEN (#Dtype = 'datetime') THEN '''1/1/1900'''
WHEN (#Dtype = 'uniqueidentifier') THEN '00000000-0000-0000-0000-000000000000'
ELSE ''''''
END )
+ ' WHERE ' + quotename(#name) +' IS NULL'
PRINT #CMD
EXEC sp_executeSQL #cmd
FETCH NEXT FROM db_cursor INTO #name, #Dtype
END
CLOSE db_cursor
DEALLOCATE db_cursor

How to save print variable into another variable in SQL Server?

Here is my script grab from net
declare #col varchar(255), #cmd varchar(max)
DECLARE getinfo cursor for
SELECT c.name
FROM sys.tables t JOIN sys.columns c
ON t.Object_ID = c.Object_ID
WHERE t.Name = 'tblDeductions'
AND c.name like 'fld%name' OPEN getinfo
FETCH NEXT FROM getinfo into #col
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #cmd = 'IF EXISTS (SELECT top 1 * FROM tblDeductions WHERE ['
+ #col + '] IS NOT NULL) BEGIN print ''
' + #col + ''' end' exec (#cmd)
FETCH NEXT FROM getinfo into #col
END CLOSE getinfo
DEALLOCATE getinfo
The above query will display column names that are null values. But I need to save them into another variable with comma separated values.
Thanks in advance.
This should work, although there's almost certainly a more efficient way to do what you're trying to do.
IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t
CREATE TABLE #t
(columnName VARCHAR(255))
DECLARE #col VARCHAR(255), #cmd VARCHAR(MAX)
DECLARE getinfo CURSOR FOR
SELECT c.name
FROM sys.tables t JOIN sys.columns c
ON t.Object_ID = c.Object_ID
WHERE t.Name = 'tblDeductions'
AND c.name LIKE 'fld%name' OPEN getinfo
FETCH NEXT FROM getinfo INTO #col
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #cmd = 'IF EXISTS (SELECT top 1 * FROM tblDeductions WHERE ['
+ #col + '] IS NOT NULL) BEGIN INSERT #t VALUES (''' + #col + ''') end'
EXEC (#cmd)
FETCH NEXT FROM getinfo INTO #col
END CLOSE getinfo
DEALLOCATE getinfo
DECLARE #columnsWithNull VARCHAR(MAX)
SET #columnsWithNull = (SELECT columnName + ','
FROM #t FOR XML PATH(''))
SET #columnsWithNull = LEFT(#columnsWithNull,LEN(#columnsWithNull) - 1)
SELECT #columnsWithNull

Resources