Search column name having specific value in tables in certain database - sql

Is there any way I can search a column having specific value I am trying to find through all tables in a database?
For example I have
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%VersionID%'
ORDER BY schema_name, table_name;
Which I found from searching. It gives me the table names that "versionID" column exists, but how can I search to return table names that for example have a value of "35" for that column.
Thanks in advance,
I apologize, maybe I am not being clear in my request. Maybe this cannot be done in SQL because I have not found anything through my research. But let me clarify.
Running this script
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%factor%'
--and table_name in (Select name from sysobjects where ratingVersionID = 35)
ORDER BY schema_name, table_name;
Will return this for example:
But let say, the "factor" column in "AutoAge_Factor" table does NOT HAVE any records matching to "35". How can I eliminate that table from returning in the results. But I would really prefer the format of the results be this way because I would like to use this return as a loop and do some other stuff within the loop.
Thanks again!

This modification to your sql will generate more SQL that you can run
SELECT
'select '''+SCHEMA_NAME(schema_id) +'.'+t.name + ''', '+c.name + ' from '
+ SCHEMA_NAME(schema_id) +'.' + t.name
+ ' where ' + c.name + ' = 35'
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%ID%'
ORDER BY schema_name(schema_id), t.name
You could make the SQL run automatically if necessary, but the syntax for that depends on your platform. Alternatively, copy the results into your query tool and run them, if that suffices

select s.name, c.name from sys.columns c inner join sys.tables s
on s.object_id = c.object_id where c.name like'%35%'
This will give you the columns with 35 and the associated table.

declare #tableName varchar(100), #colName varchar(100) declare
#sqlStatement nvarchar(100)
declare tablelist cursor for select s.name, c.name from sys.columns
c inner join sys.tables s on s.object_id = c.object_id where c.name
like'%YourSearchCondtion%' OPEN tablelist FETCH NEXT FROM tablelist
into #tableName, #colName
while ##FETCH_STATUS = 0 BEGIN
SELECT #sqlStatement = 'SELECT ' + #colName + ', * FROM ' + #tableName
+ ' WHERE ' + #colName + ' NOT LIKE ''%35%'''
exec sp_executesql #sqlStatement
-- Here you can get the table that you dont want and add to a temp table.. PRINT CAST(##ROWCOUNT AS VARCHAR)
FETCH NEXT FROM tablelist INTO #tableName, #colName END
CLOSE tablelist DEALLOCATE tablelist GO

Related

Retrieving which database(s) and tables contains a spesific column name within a multiple database soloution

I wish do retrieve the database which contains table x, based on a column name I enter through e.g. My WHERE statement.
As of now, I run two seperate SELECT queries. Firstly, I search for which tables in the soloution contains a spesific column.
Second, I have to manually search for all the resulting databases in the subquery.
I wish to have this dynamic, so that when entering the column name, both database and table are returned. Now, I get "NULL" the Database column.
I've managed to get the current db using only db_name, but that is not what I intend to do..
db_name(db_id(table1.name)) AS "Database" , table1.name AS 'Table', column1.name AS 'Column'
FROM sys.columns column1
JOIN sys.tables table1 ON column1.object_id = table1.object_id
WHERE column1.name LIKE 'columnname'
ORDER BY "Table", "Column"
(SELECT "db" FROM sys.databases WHERE CASE WHEN state_desc = 'ONLINE' THEN
OBJECT_ID(QUOTENAME("db") + '.[dbo].' + '[database1]', 'U')
END IS NOT NULL)
The code above is working wiithout errors. However, I do not manage to pull the Database name, and I can not understand how I could solve this.
I've used several earlier posts as reference to build up this code, as I'm a rookie to SQL.. :-)
Thanks in advance for any assitance.
Br.
This gives a bit more information than you requested, but it's a code that I had to create a data dictionary of my databases. You just need to change the value for the first variable to make it work.
--Change this value
DECLARE #ColumnName sysname = 'YourColumnName';
IF OBJECT_ID( 'tempdb..#DataDictionary') IS NOT NULL
DROP TABLE #DataDictionary;
CREATE TABLE #DataDictionary(
TABLE_CATALOG sysname,
TABLE_SCHEMA sysname,
TABLE_NAME sysname,
ORDINAL_POSITION int,
COLUMN_NAME sysname,
DATA_TYPE sysname,
IS_NULLABLE varchar(8)
);
DECLARE #SQL NVARCHAR(MAX);
DECLARE dbs CURSOR LOCAL FAST_FORWARD
FOR
SELECT REPLACE( 'USE <<database_name>>;
INSERT INTO #DataDictionary
SELECT DB_NAME() AS TABLE_CATALOG,
s.name AS TABLE_SCHEMA,
t.name AS TABLE_NAME,
COLUMNPROPERTY(c.object_id, c.name, ''ordinal'') AS ORDINAL_POSITION,
c.name AS COLUMN_NAME,
CASE WHEN ty.name IN (''char'', ''varchar'', ''varbinary'', ''binary'') THEN CONCAT( ty.name, ''('', ISNULL( CAST(NULLIF(c.max_length, -1) AS varchar(4)), ''MAX''), '')'')
WHEN ty.name IN (''nchar'', ''nvarchar'') THEN CONCAT( ty.name, ''('', ISNULL( CAST(NULLIF(c.max_length, -1)/2 AS varchar(4)), ''MAX''), '')'')
WHEN ty.name IN (''numeric'', ''decimal'') THEN CONCAT( ty.name, ''('', c.precision, '','', c.scale, '')'')
ELSE ty.name END AS DATA_TYPE,
IIF(c.is_nullable = 1, ''NULL'', ''NOT NULL'') AS IS_NULLABLE
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types ty ON c.user_type_id = ty.user_type_id
WHERE t.object_id NOT IN( SELECT major_id FROM sys.extended_properties WHERE minor_id = 0 AND class = 1 AND name = N''microsoft_database_tools_support'')
AND c.name = #ColumnName;', '<<database_name>>', name)
FROM sys.databases
WHERE database_id > 4 --No system databases
AND HAS_DBACCESS( name) = 1
AND state_desc = 'ONLINE'
OPEN dbs;
FETCH NEXT FROM dbs INTO #SQL;
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC sp_executesql #SQL, N'#ColumnName sysname', #ColumnName;
FETCH NEXT FROM dbs INTO #SQL;
END;
CLOSE dbs;
DEALLOCATE dbs;
SELECT *
FROM #DataDictionary
ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION;
To get all the columns, just remove the column name comparison in the dynamic code AND c.name = #ColumnName

Find text in my tables, stored procedures, and views in SQL Server

I am able to search for specific text in my views and stored procedure, but I'm not able to search through my tables at the same time.
Here is what I have:
DECLARE #cmd VARCHAR(1000),
#search_string VARCHAR(200)
CREATE TABLE #temp
(
[Database_Name] sysname,
[Schema_Name] sysname,
[Object_Name] sysname,
[Object_Type] nvarchar(60)
)
-- Set the search string
SET #search_string = 'text'
SET #cmd = 'INSERT INTO #temp SELECT DISTINCT ''?'', s.name AS Schema_Name, o.name AS Object_Name, o.type_desc FROM [?].sys.sql_modules m INNER JOIN [?].sys.objects o ON m.object_id = o.object_id INNER JOIN [?].sys.schemas s ON o.schema_id = s.schema_id WHERE m.definition Like ''%' + #search_string + '%'''
-- Uncomment the following if you have problems with your command and want to see the command
--PRINT #cmd
-- Run for every database on the server
EXEC sp_MSforeachdb #cmd
-- Retrieve your results from the temp table
SELECT *
FROM #temp
ORDER BY [Database_Name], [Object_Name], [Object_Type]
-- If you want to omit certain databases from your results, simply add
-- the appropriate WHERE clause, as in the following:
--SELECT *
--FROM #temp
--WHERE db NOT IN ('DB1', 'DB4', 'DB7')
--ORDER BY db, obj_type, obj_name
DROP TABLE #temp
Please try this query for column search
SELECT
t.[name] TableName
, c.[name] ColumnName
FROM sys.columns c
INNER JOIN sys.tables t on t.object_id = c.object_id
WHERE t.[type] = 'U'
AND c.[name] LIKE '%Text%'
Below script will get result for all the databases for both Tables and other obejcts. Hope this will help.
DECLARE #command varchar(1000)
DECLARE #SearchWord VARCHAR(20) = 'Text'
CREATE TABLE #Search (DatabaseName VARCHAR(255),SchemaName VARCHAR(50),ObjectName VARCHAR(255),ObjectType VARCHAR(50))
SET #command = 'USE ? INSERT INTO #Search
SELECT DB_NAME(), SCHEMA_NAME(t.schema_id),t.[name] TableName, ''Table'' FROM sys.columns c INNER JOIN sys.tables t on t.object_id = c.object_id WHERE t.[type] = ''U'' AND c.[name] LIKE ' + '''%' + #SearchWord + '%'''
EXEC sp_MSforeachdb #command;
SET #command = 'USE ? INSERT INTO #Search
SELECT DISTINCT DB_Name(),s.name AS Schema_Name, o.name AS Object_Name, o.type_desc FROM sys.sql_modules m INNER JOIN sys.objects o ON m.object_id = o.object_id INNER JOIN sys.schemas s ON o.schema_id = s.schema_id WHERE m.definition Like ''%' + #SearchWord + '%'''
EXEC sp_MSforeachdb #command
SELECT * FROM #Search;
DROP TABLE #Search
There is an easy way
select
object= object_name(c.id), o.name , o.type
from sys.syscomments as c
join sys.objects as o on c.id = o.object_id
where c.text like '%Id%'
All compiled objects are in sys.comments, the name changed a few times depending on the version of SQL you have, the sample is from the current version.
Now, one doesn't need to join sys.object as the TSQL is in the text column.
You can look for any string that you have used, table names, field names or code comments. the sample shows %ID% looking for all function, trigger, views procedures that have something that contains the letters ID.
You know that when clicking on an object in SSMS you can select show Dependencies right?

SQL Column Name wildcard

I have a table with 30+ fields and I want to quickly narrow my selection down to all fields where column name start with 'Flag'.
select * Like Flag% from Table1
You will want to build a dynamic query as explained here: https://stackoverflow.com/a/4797728/9553919
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'Foods'
AND table_schema = 'YourDB'
AND column_name LIKE 'Vegetable%'
This SQL Statement should be useful. You may be able to simplify it but it does work.
Edit2: I just now saw your pervasive-sql tag. Unfortunately I've never worked with that and don't know if the syntax is compatible with MS SQL Server. I'll let my answer here in case it helps others, but wanted to share that I tested this using SQL Server.
Edit: SCHEMA_NAME function isn't necessary. You can replace SCHEMA_NAME(schema_id) with the name of your schema in single quotes if you want, but either will work.
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM
sys.tables AS t
INNER JOIN
sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE
t.name = 'Table1' AND
c.name Like 'Flag%'
ORDER BY
c.name
or
SELECT t.name AS table_name,
'MySchema' AS schema_name,
c.name AS column_name
FROM
sys.tables AS t
INNER JOIN
sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE
t.name = 'Table1' AND
c.name Like 'Flag%'
ORDER BY
c.name
To do this, you will need to query the system tables for the columns associated to the table and filter them to what you want. From there, place them into a variable table and create a CSV of columns. From there, you can dynamically construct your query as needed. The below example should help you get started.
DECLARE #tableName VARCHAR(100) = 'dbo.SomeTable'
DECLARE #columnNames TABLE
(
Id INT IDENTITY PRIMARY KEY,
ColumnName VARCHAR(100)
)
--Grabs all of the columns into a variable table
INSERT INTO #columnNames (ColumnName)
SELECT
[name]
FROM sys.columns
WHERE
[object_id] = OBJECT_ID(#tableName)
AND
[name] LIKE '%Flag'
DECLARE #columns VARCHAR(1000)
--Creates a CSV of columns
SET #columns =
STUFF(
(
SELECT
',' + ColumnName
FROM #columnNames
FOR XML PATH(''))
,1,1,'')
DECLARE #selectStatement NVARCHAR(4000) = CONCAT('SELECT ', #columns, ' FROM ', #tableName)
PRINT #selectStatement
EXEC #selectStatement

List of all tables that contains specific data in column

With this query, I get all tables that contains column named "Status_ID"
SELECT
c.name AS 'ColumnName'
,t.name AS 'TableName'
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE 'Status_ID'
Data in Status_ID may only have values from 1 to 6.
What I want is to get a list of all tables, where Status_ID = 2 at least once.
(Exclude all tables from the code above, that do not contain data with Status_ID = 2)
Solution 1:
Run the below query, which will give you a select query with all the tables containing status_id column. then copy and execute the select query to find the data.
SELECT 'select * from ' + TABLE_NAME + ' where Status_ID = ''2'''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'Status_ID'
Solution 2:
You may need to use the following solution to find the data in all tables
Find a string by searching all tables in SQL Server Management Studio 2008
This should do the trick:
DECLARE #sql NVARCHAR(MAX) = 'DECLARE #tables NVARCHAR(MAX) = '''' ;' ;
DECLARE #tables NVARCHAR(MAX) = '';
SELECT #SQL += 'IF EXISTS (SELECT ''X'' FROM ' + QUOTENAME(t.name)
+ 'WHERE STATUS_ID =2) SET #tables+= ' + '''' + + ',' +
QUOTENAME(t.name) + ''''
+ ';'
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE 'STATUS_ID'
SET #sql += 'SELECT SUBSTRING(#TABLES,2,LEN(#TABLES));'
EXEC(#SQL);

Find a column name from all tables and all databases with specified column name SQL Server

I have several databases and I want to find a column name from my all databases with all tables.
This query gives me only list of all tables from just one database but I want all databases name with all tables name
SELECT
t.name,c.name
FROM
sys.tables t
INNER JOIN
sys.columns c ON c.object_id = t.object_id
WHERE
c.name LIKE '%CUSTOMERID%'
Thanks
There are times when sp_foreachdb will just skip databases. Remember that it is an undocumented system procedure and as such there may be bugs in it. For something like this I prefer to just some dynamic sql. It isn't much more code than the undocumented cursor but it is more accurate.
declare #SQL nvarchar(max) = ''
select #SQL = #SQL + 'SELECT ''' + d.name + ''' as DatabaseName, t.name as TableName, c.name as ColumnName FROM ' + d.name + '.sys.tables t inner join ' + d.name + '.sys.columns c ON c.object_id = t.object_id WHERE c.name LIKE ''%CUSTOMERID%'' union all '
from sys.databases d
where d.name not in('master', 'tempdb', 'msdb', 'model', 'ReportServer', 'ReportServerTempDB')
set #SQL = left(#SQL, len(#SQL) - 10)
exec sp_executesql #SQL
Use
exec sp_msforeachdb
Example:
exec sp_msforeachdb 'use ? select top 10 * from sys.tables'
It basically executes a dynamic sql statement on each database. the '?' character is replaced with the current database it's iterating through. Use with care.