Search of table names - sql

I use the following to search for strings within the stored procedures of a specific database:
USE DBname
SELECT Name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%xxx%'
Is it easy to amend the above so that it searches Table names in a specific db "DBname" ?

I'm using this and works fine
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%%'

select name
from DBname.sys.tables
where name like '%xxx%'
and is_ms_shipped = 0; -- << comment out if you really want to see them

If you want to look in all tables in all Databases server-wide and get output you can make use of the undocumented sp_MSforeachdb procedure:
sp_MSforeachdb 'SELECT "?" AS DB, * FROM [?].sys.tables WHERE name like ''%Table_Names%'''

You can also use the Filter button to filter tables with a certain string in it.
You can do the same with stored procedures and views.

I am assuming you want to pass the database name as a parameter and not just run:
SELECT *
FROM DBName.sys.tables
WHERE Name LIKE '%XXX%'
If so, you could use dynamic SQL to add the dbname to the query:
DECLARE #DBName NVARCHAR(200) = 'YourDBName',
#TableName NVARCHAR(200) = 'SomeString';
IF NOT EXISTS (SELECT 1 FROM master.sys.databases WHERE Name = #DBName)
BEGIN
PRINT 'DATABASE NOT FOUND';
RETURN;
END;
DECLARE #SQL NVARCHAR(MAX) = ' SELECT Name
FROM ' + QUOTENAME(#DBName) + '.sys.tables
WHERE Name LIKE ''%'' + #Table + ''%''';
EXECUTE SP_EXECUTESQL #SQL, N'#Table NVARCHAR(200)', #TableName;

If you prefer case-insensitive searching:
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME ILIKE '%%'
or
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE Lower(TABLE_NAME) LIKE Lower('%%')

Adding on to #[RichardTheKiwi]'s answer.
Whenever I search for a list of tables, in general I want to select from all of them or delete them. Below is a script that generates those scripts for you.
The generated select script also adds a tableName column so you know what table you're looking at:
select 'select ''' + name + ''' as TableName, * from ' + name as SelectTable,
'delete from ' + name as DeleteTable
from sys.tables
where name like '%xxxx%'
and is_ms_shipped = 0;

you can also use the show command.
show tables like '%tableName%'

I want to post a simple solution for every schema you've got. If you are using MySQL DB, you can simply get from your schema all the table's name and add the WHERE-LIKE condition on it. You also could do it with the usual command line as follows:
SHOW TABLES WHERE tables_in_<your_shcema_name> LIKE '%<table_partial_name>%';
where tables_in_<your_shcema_name> returns the column's name of SHOW TABLES command.

You can use below :
Select * from sys.tables where name like '%yourtablename%'

This will working fine....
SELECT * FROM sys.TABLES
WHERE name LIKE '%%'

Related

In One DB I have 100+ tables, but I need staging table (start with STR_) wise column wise(Which is Status ) row count. in Dynamic query [duplicate]

I am trying to write this query to find all tables with specific column with some specific value. This is what I've done so far -
EXEC sp_MSforeachtable
#command1='
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=PARSENAME("?",2) AND TABLE_NAME=PARSENAME("?",1) AND COLUMN_NAME="EMP_CODE")
BEGIN
IF (SELECT COUNT(*) FROM ? WHERE EMP_CODE="HO081")>0
BEGIN
SELECT * FROM ? WHERE EMP_CODE="HO081"
END
END
'
I hope my intensions are clear, I just want to select only those tables where the column EMP_CODE is present and in those tables I want to select those rows where EMP_CODE='HO081'.
Edit -
Now it stands like this. But I'm not able to replace #EMPCODE variable in the query.
DECLARE #EMPCODE AS VARCHAR(20)
SET #EMPCODE='HO081'
EXEC sp_MSforeachtable
#command1='
DECLARE #COUNT AS INT
SELECT #COUNT=COUNT(*) FROM ? WHERE EMP_CODE='''+#EMPCODE+'''
IF #COUNT>0
BEGIN
PRINT PARSENAME("?",1)+'' => ''+CONVERT(VARCHAR,#COUNT)+'' ROW(S)''
--PRINT ''DELETE FROM ''+PARSENAME("?",1)+'' WHERE EMP_CODE='''''+#EMPCODE+'''''''
END
',#whereand='AND O.ID IN (SELECT OBJECT_ID FROM SYS.COLUMNS C WHERE C.NAME='''+#EMPCODE+''')'
You know how sp_MSforeachtable is undocumented, and may go away at any time/be modified?
Well, if you're happy to ignore that, it has another parameter called #whereand, which is appended to the WHERE clause of the internal query that is being used to find the tables (and should start with an AND).
You also have to know that there's an alias, o against sysobjects, and a second alias syso against sys.all_objects.
Using this knowledge, you might craft your #whereand parameter as:
EXEC sp_MSforeachtable
#command1='...',
#whereand='AND o.id in (select object_id from sys.columns c where c.name=''EMP_CODE'')'
You can now also simplify your command1, since you know it will only be run against tables containing an EMP_CODE column. I'd probably take out the COUNT(*) condition also, since I don't see what value it's adding.
Updated based on your further work, and tested against one table:
DECLARE #EMPCODE AS VARCHAR(20)
SET #EMPCODE='HO081'
declare #sql nvarchar(2000)
set #sql = '
DECLARE #COUNT AS INT
SELECT #COUNT=COUNT(*) FROM ? WHERE EMP_CODE='''+#EMPCODE+'''
IF #COUNT>0
BEGIN
PRINT PARSENAME("?",1)+'' => ''+CONVERT(VARCHAR,#COUNT)+'' ROW(S)''
--PRINT ''DELETE FROM ''+PARSENAME("?",1)+'' WHERE EMP_CODE='''''+#EMPCODE+'''''''
END
'
EXEC sp_MSforeachtable
#command1=#sql,#whereand='AND O.ID IN (SELECT OBJECT_ID FROM SYS.COLUMNS C WHERE C.NAME=''EMP_CODE'')'
(I've reverted the #whereand to query for EMP_CODE, since you don't want to replace the value there).
The issue is that, you can pass parameters to a stored procedure, or literals, but you can't perform calculations/combining actions between them - so I moved the construction of the sql statement out into a separate action.
I guess you get an error of some kind, perhaps Invalid column name 'EMP_CODE'?
It's because the code is compiled before you check for the column.
You could do like this instead.
EXEC sp_MSforeachtable
#command1='
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=PARSENAME("?",2) AND TABLE_NAME=PARSENAME("?",1) AND COLUMN_NAME="EMP_CODE")
BEGIN
EXEC(''
IF (SELECT COUNT(*) FROM ? WHERE EMP_CODE="HO081")>0
BEGIN
SELECT * FROM ? WHERE EMP_CODE="HO081"
END
'')
END
'

Select on multiple tables which are a result of an other select

I need to create a function which searches all the tables that contain a certain field
select distinct(table_name) from information_schema.columns where column_name='fieldNeeded';
and then, to do a query on each table that is found:
select * from table_name where ... <parameters> ;
Is there a way to do so?
If you use SQL-server...
You can use the result of the first query is input for your cursor (a for-loop in T-SQL) in where you dynamically create and execute the query. Note 'dynamic sql' is creating an sql-command in string (varchar) format and then run that string as sql-commant (something like: EXEC #SqlCommand), although there are other (better) ways to execute dynamic sql.
To finish things up nicely, you can start with creating a temp-table and insert the result in the temp-table. And in each iteration of the cursor you can store the result in the temp-table
In pseudo-code it would look something like:
Create #TempTable with some columns
Create Cursor for:
select distinct(table_name)
from information_schema.columns
where column_name='fieldNeeded'
For each element in the cursor (fetch next #table_name from the cursor)
DECLARE #SqlCommand VARCHAR(250) =
'Insert Into #TempTable select * from ' + #table_name + 'where ... <parameters>'
PRINT #SqlCommand -- can be useful to check the code you created
EXEC #SqlCommand
End of cursor
SELECT * FROM #TempTable

How to search for specific column name within one table

I have searched this question on stackoverflow but most of the questions are a little deeper than what I want. Many questions are relating to finding the table that has the specific column name.
I am connected to the database through SSMS. I have found the table that I want to search through by SELECT * FROM Item. In the Item table I want to search all of the field names (or name of the column) and select the ones that contain a specific string 'Size'. I thought something like this would work
Select * FROM Item WHERE column_name LIKE '%SIZE%'
It doesn't work though. How do I specify it to search through all of the column names to find the names that contain 'Size'?
Thanks.
This should be the generic query to get you to what you want.
USE [database_name]
GO
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 '%SIZE%'
AND t.name = 'Item'
ORDER BY schema_name, table_name;
You will need the correct permission on whichever SQL login that you run this through.
SELECT [Name]
FROM sys.columns
WHERE OBJECT_NAME(object_id)='Item'
AND [Name] LIKE '%Size%';
You can use
SELECT * FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME ='zzzzz' and COLUMN_NAME like '%size%'
This looks through table named Item for a Column with the name like 'SIZE':
SELECT sch.COLUMN_NAME, sch.*
FROM INFORMATION_SCHEMA.COLUMNS AS sch
WHERE TABLE_NAME = 'Item'
AND COLUMN_NAME LIKE '%SIZE%'
Is this what you wanted?
I think this is what you are looking for, just replace database_Name with your db name:
Declare #myQuery varchar(max) = ' Select ';
Declare #columnName varchar(max) = '';
Declare GetColumnNames Cursor
For
SELECT COLUMN_NAME
FROM database_Name.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'Item'
And database_Name.INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME like '%SIZE%'
OPEN GetColumnNames
FETCH NEXT FROM GetColumnNames
INTO #columnName
WHILE ##FETCH_STATUS = 0
BEGIN
Set #myQuery += #columnName + ', '
FETCH NEXT FROM GetColumnNames
INTO #columnName
END
CLOSE GetColumnNames;
DEALLOCATE GetColumnNames;
-- Chop off the end character
SET #myQuery = LEFT(#myQuery, LEN(#myQuery) - 1)
Set #myQuery += ' From Item'
exec(#myQuery)
You'll have to take a two step approach to achieve your end query.
First, you'll need to identify the columns you're interested in by using the table metadata, which you can get from either the sys schema or the INFORMATION_SCHEMA tables. Several of the proposed answers will help you get that information.
Next, you'll use the column names you've identified in step one to build the actual query you're interested in. If this is a one-off task you're doing, just copy and paste the results from the meta data query into a new SELECT query as your column list. If you need to do this task programmatically or multiple times using different LIKE strings, then you'll want to invest the time in writing some dynamic SQL.
When you wrap it all up, it'll look something like this:
--Step 1; The meta data part
DECLARE #ColumnList NVARCHAR(MAX)
,#SQL NVARCHAR(MAX)
SELECT
#ColumnList = COALESCE(#ColumnList+',','') + COLUMN_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = 'schema'
AND
TABLE_NAME = 'TableName'
AND
COLUMN_NAME LIKE '%SIZE%'
SELECT #ColumnList;
--Step 2; The dynamic SQL part
SET #SQL = 'SELECT ' + #ColumnList + ' FROM schema.TableName;';
EXECUTE sys.sp_executesql #SQL;

Get table name from database field

I use SQL Server Management Studio 17.0. I have a table which controls separate tables for different files, something like:
filename | tablename
---------+----------
file1 | table1
file2 | table2
I need to select from tablename, but not hardcoded. Filename comes from web, and I can fist get the tablename, like
select tablename
from filetables
where filename = "file1"
and use it to view the file table:
select *
from (table1)
Is there any way to do it in SQL? Something like
Select *
from
(select tablename
from filetables
where filename = "file1")
You can't select from a table that can only be determined at run time and/or depending on some parameter. Your only option is to use a Dynamic SQL in this case but make sure you don't expose yourself to SQL-Injection attacks.
Here's a link on how to safely create Dynamic SQL.
DECLARE #v_sql NVARCHAR(MAX),
#v_table_name NVARCHAR(MAX),
#v_file_name NVARCHAR(MAX)
SELECT #v_file_name = 'file1' -- Populated from web proc
SELECT #v_table_name = tablename
FROM filetables
WHERE filename = REPLACE(#v_file_name, '''', '')
SELECT #v_sql =
'SELECT *
FROM ' + #v_table_name + '
WHERE filename = ''' + #v_file_name + ''''
SELECT #v_sql -- Debug code to show you the statement prior to running
EXEC sp_executesql #v_sql
You will need to utilize dynamic SQL like other users here have answered. Give this a shot in your environment and see how it goes.

Find a database with a particular table OR Find a table in every database of SQL Server

I have a SQL Server with hundreds of databases and each database having hundreds of tables.
Now I would like to find where in these databases is a table that I am looking for.
I could find if a table existed in individual database using
use myDatabase
select * from sys.tables where name = 'mytable'
GO
but using this means I have to manually change the database for hundreds of times .
I would like to find the database name only.
Is there a way out ?
Okay, if you're just wanting to find each database that contains a particular table, and aren't going to be querying the table, then you can just do:
create table #t (
DBName sysname not null
)
go
exec sp_MSforeachdb 'use [?]; if OBJECT_ID(''dbo.mytable'') is not null insert into #t (DBName) select ''?'''
go
select * from #t
go
drop table #t
(If you're not using multiple schemas in your databases, you won't need to specify dbo in the OBJECT_ID call, otherwise I use it to avoid finding tables in the wrong schema)
This should do what you are looking for:
EXEC sp_MSforeachdb "use [?];select * from sys.tables where name='TableName' "
To include the name of the current database in the output use:
EXEC sp_MSforeachdb "use [?];select '[?]' as DatabaseName, * from sys.tables where name='TableName' "
SELECT DISTINCT DB_NAME(database_id)
FROM [sys].[dm_db_index_operational_stats](NULL,NULL,NULL,NULL)
WHERE OBJECT_NAME(object_id,database_id) = 'mytable'
I know this is an old thread but was high on my google search. So I wanted to contribute for others looking to find a database with a certain table in it. These apply to SQL Server 2008 - Current.
I started with this, which worked for my SA level login, but gave me issues with users that did not have permissions to all databases.
SELECT name
FROM sys.databases
WHERE CASE
WHEN state_desc = 'ONLINE' THEN OBJECT_ID( QUOTENAME( name ) + '.[dbo].[mytablename]','U' )
END IS NOT NULL;
But ended up with this adding the HAS_DBACCESS(name) = 1 in restriction so that the query would not fail with a security error.
SELECT name
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1 and
CASE
WHEN state_desc = 'ONLINE' THEN OBJECT_ID( QUOTENAME( name ) + '.[dbo].[mytablename]','U' )
END IS NOT NULL;
exec sp_msforeachdb #command1='
USE ?;
select * from sys.tables where name = ''CLIENTS'''
this is also one of the way, similar with solution of #Jonathan :
exec sp_MSforeachdb 'SELECT "?" AS DB, * FROM [?].sys.tables WHERE name like ''%YourTableName%'''
exec 'select ''?'', name from [?].sys.tables where name = ''yourTable'''