Related
I am trying to update a table using table type parameter. Currently I am using the below query. But I would like to perform update in batches having batch size as one of the parameters. Kindly help.
ALTER PROCEDURE UPDATEStatus
#Ids int ,
#numbers TypeofNumbers readonly,
#Status char(2),
#nname varchar(50),
AS
BEGIN
BEGIN TRY
update e
set
e.status = #Status,
e.user =#nname,
e.time = GETDATE()
from detailtable e
join #numbers en on en.ID =e.ID
where e.oddIDs = #Ids
I tried to do in a single update but I wanted to do in sets or batches one by one. say 100 records first and then next 100 records until all are done
You can use something like this to do your update in batches:
CREATE OR ALTER PROCEDURE UPDATEStatus
#Ids INT,
#numbers TypeOfNumbers READONLY,
#Status CHAR(2),
#nname VARCHAR(50)
AS
BEGIN
DECLARE #UpdatedRows INT;
DECLARE #Skip INT = 0;
DECLARE #BatchSize INT = 100;
WHILE ISNULL(#UpdatedRows, 1) > 0
BEGIN
WITH CTE
AS (SELECT *
FROM #numbers AS n
ORDER BY n.ID OFFSET #Skip * #BatchSize ROWS FETCH NEXT #BatchSize ROWS ONLY)
UPDATE e
SET
e.[Status] = #Status,
e.[User] = #nname,
e.[time] = GETDATE()
FROM CTE AS en
JOIN detailtable e ON en.ID = e.ID;
SET #UpdatedRows = ##ROWCOUNT;
SET #Skip = #Skip + 1;
END;
END;
GO
Next time please also provide scripts for the DDL and some testdata.
I'm trying to write a stored procedure to search for a string in all tables of a SQL Server database. I was able to find a good stored procedure for this purpose
However I don't want to just put the #Tablenames manually, I want it to go to a table called Enums_Tables that has an ID, and use that ID as #Tablenames.
What I have being thinking to solve this:
I could write another stored procedure to select all Id's from Enums_Tables and execute the first stored procedure, like in here
I could also pass the parameter in C#, since I'm going to use it as a search textbox. But the ideal would be making a single stored procedure.
Could you please help me with this?
EDIT
Thanks to GPW I have been able to solve this problem. I also encountered problems with the collation, but I also solve it. Below is the final stored procedure.
USE [DynaForms]
GO
/****** Object: stored procedure [dbo].[SP_SearchTables] Script Date: 09/11/2017 14:59:15 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_SearchTables]
--#Tablenames VARCHAR(500)
#SearchStr NVARCHAR(60)
,#GenerateSQLOnly Bit = 0
,#SchemaNames VARCHAR(500) ='%'
AS
/*
Parameters and usage
#Tablenames -- Provide a single table name or multiple table name with comma seperated.
If left blank , it will check for all the tables in the database
Provide wild card tables names with comma seperated
EX :'%tbl%,Dim%' -- This will search the table having names comtains "tbl" and starts with "Dim"
#SearchStr -- Provide the search string. Use the '%' to coin the search. Also can provide multiple search with comma seperated
EX : X%--- will give data staring with X
%X--- will give data ending with X
%X%--- will give data containig X
%X%,Y%--- will give data containig X or starting with Y
%X%,%,,% -- Use a double comma to search comma in the data
#GenerateSQLOnly -- Provide 1 if you only want to generate the SQL statements without seraching the database.
By default it is 0 and it will search.
##SchemaNames -- Provide a single Schema name or multiple Schema name with comma seperated.
If left blank , it will check for all the tables in the database
Provide wild card Schema names with comma seperated
EX :'%dbo%,Sales%' -- This will search the Schema having names comtains "dbo" and starts with "Sales"
Samples :
1. To search data in a table
EXEC SP_SearchTables #Tablenames = 'T1'
,#SearchStr = '%TEST%'
The above sample searches in table T1 with string containing TEST.
2. To search in a multiple table
EXEC SP_SearchTables #Tablenames = 'T2'
,#SearchStr = '%TEST%'
The above sample searches in tables T1 & T2 with string containing TEST.
3. To search in a all table
EXEC SP_SearchTables #Tablenames = '%'
,#SearchStr = '%TEST%'
The above sample searches in all table with string containing TEST.
4. Generate the SQL for the Select statements
EXEC SP_SearchTables #Tablenames = 'T1'
,#SearchStr = '%TEST%'
,#GenerateSQLOnly = 1
5. To Search in tables with specfic name
EXEC SP_SearchTables #Tablenames = '%T1%'
,#SearchStr = '%TEST%'
,#GenerateSQLOnly = 0
6. To Search in multiple tables with specfic names
EXEC SP_SearchTables #Tablenames = '%T1%,Dim%'
,#SearchStr = '%TEST%'
,#GenerateSQLOnly = 0
7. To specify multiple search strings
EXEC SP_SearchTables #Tablenames = '%T1%,Dim%'
,#SearchStr = '%TEST%,TEST1%,%TEST2'
,#GenerateSQLOnly = 0
8. To search comma itself in the tables use double comma ",,"
EXEC SP_SearchTables #Tablenames = '%T1%,Dim%'
,#SearchStr = '%,,%'
,#GenerateSQLOnly = 0
EXEC SP_SearchTables #Tablenames = '%T1%,Dim%'
,#SearchStr = '%with,,comma%'
,#GenerateSQLOnly = 0
9. To Search by SchemaName
EXEC SP_SearchTables #Tablenames = '%T1%,Dim%'
,#SearchStr = '%,,%'
,#GenerateSQLOnly = 0
,#SchemaNames = '%dbo%,Sales%'
*/
SET NOCOUNT ON
DECLARE #MatchFound BIT
SELECT #MatchFound = 0
DECLARE #CheckTableNames Table
(
Schemaname sysname
,Tablename sysname
)
DECLARE #SearchStringTbl TABLE
(
SearchString VARCHAR(500)
)
DECLARE #SQLTbl TABLE
(
Tablename SYSNAME
,WHEREClause VARCHAR(MAX)
,SQLStatement VARCHAR(MAX)
,Execstatus BIT
)
DECLARE #SQL VARCHAR(MAX)
DECLARE #TableParamSQL VARCHAR(MAX)
DECLARE #SchemaParamSQL VARCHAR(MAX)
DECLARE #TblSQL VARCHAR(MAX)
DECLARE #tmpTblname sysname
DECLARE #ErrMsg VARCHAR(100)
/*
IF LTRIM(RTRIM(#Tablenames)) IN ('' ,'%')
BEGIN
INSERT INTO #CheckTableNames
SELECT Name
FROM sys.tables
END
ELSE
BEGIN
IF CHARINDEX(',',#Tablenames) > 0
SELECT #SQL = 'SELECT ''' + REPLACE(#Tablenames,',','''as TblName UNION SELECT ''') + ''''
ELSE
SELECT #SQL = 'SELECT ''' + #Tablenames + ''' as TblName '
SELECT #TblSQL = 'SELECT T.NAME
FROM SYS.TABLES T
JOIN (' + #SQL + ') tblsrc
ON T.name LIKE tblsrc.tblname '
INSERT INTO #CheckTableNames
EXEC(#TblSQL)
END
*/
--IF LTRIM(RTRIM(#Tablenames)) = ''
--BEGIN
-- SELECT #Tablenames = '%'
--END
IF LTRIM(RTRIM(#SchemaNames)) =''
BEGIN
SELECT #SchemaNames = '%'
END
--IF CHARINDEX(',',#Tablenames) > 0
-- SELECT #TableParamSQL = 'SELECT ''' + REPLACE(#Tablenames,',','''as TblName UNION SELECT ''') + ''''
--ELSE
-- SELECT #TableParamSQL = 'SELECT ''' + #Tablenames + ''' as TblName '
IF CHARINDEX(',',#SchemaNames) > 0
SELECT #SchemaParamSQL = 'SELECT ''' + REPLACE(#SchemaNames,',','''as SchemaName UNION SELECT ''') + ''''
ELSE
SELECT #SchemaParamSQL = 'SELECT ''' + #SchemaNames + ''' as SchemaName '
SELECT #TblSQL = 'SELECT SCh.NAME,T.NAME
FROM SYS.TABLES T
JOIN SYS.SCHEMAS SCh
ON SCh.SCHEMA_ID = T.SCHEMA_ID
INNER JOIN [DynaForms].[dbo].[Enums_Tables] et on
(et.Id = T.NAME COLLATE Latin1_General_CI_AS)'
INSERT INTO #CheckTableNames
(Schemaname,Tablename)
EXEC(#TblSQL)
IF NOT EXISTS(SELECT 1 FROM #CheckTableNames)
BEGIN
SELECT #ErrMsg = 'No tables are found in this database ' + DB_NAME() + ' for the specified filter'
PRINT #ErrMsg
RETURN
END
IF LTRIM(RTRIM(#SearchStr)) =''
BEGIN
SELECT #ErrMsg = 'Please specify the search string in #SearchStr Parameter'
PRINT #ErrMsg
RETURN
END
ELSE
BEGIN
SELECT #SearchStr = REPLACE(#SearchStr,',,,',',#DOUBLECOMMA#')
SELECT #SearchStr = REPLACE(#SearchStr,',,','#DOUBLECOMMA#')
SELECT #SearchStr = REPLACE(#SearchStr,'''','''''')
SELECT #SQL = 'SELECT ''' + REPLACE(#SearchStr,',','''as SearchString UNION SELECT ''') + ''''
INSERT INTO #SearchStringTbl
(SearchString)
EXEC(#SQL)
UPDATE #SearchStringTbl
SET SearchString = REPLACE(SearchString ,'#DOUBLECOMMA#',',')
END
INSERT INTO #SQLTbl
( Tablename,WHEREClause)
SELECT QUOTENAME(SCh.name) + '.' + QUOTENAME(ST.NAME),
(
SELECT '[' + SC.Name + ']' + ' LIKE ''' + REPLACE(SearchSTR.SearchString,'''','''''') + ''' OR ' + CHAR(10)
FROM SYS.columns SC
JOIN SYS.types STy
ON STy.system_type_id = SC.system_type_id
AND STy.user_type_id =SC.user_type_id
CROSS JOIN #SearchStringTbl SearchSTR
WHERE STY.name in ('varchar','char','nvarchar','nchar','text')
AND SC.object_id = ST.object_id
ORDER BY SC.name
FOR XML PATH('')
)
FROM SYS.tables ST
JOIN #CheckTableNames chktbls
ON chktbls.Tablename = ST.name
JOIN SYS.schemas SCh
ON ST.schema_id = SCh.schema_id
AND Sch.name = chktbls.Schemaname
WHERE ST.name <> 'SearchTMP'
GROUP BY ST.object_id, QUOTENAME(SCh.name) + '.' + QUOTENAME(ST.NAME) ;
UPDATE #SQLTbl
SET SQLStatement = 'SELECT * INTO SearchTMP FROM ' + Tablename + ' WHERE ' + substring(WHEREClause,1,len(WHEREClause)-5)
DELETE FROM #SQLTbl
WHERE WHEREClause IS NULL
WHILE EXISTS (SELECT 1 FROM #SQLTbl WHERE ISNULL(Execstatus ,0) = 0)
BEGIN
SELECT TOP 1 #tmpTblname = Tablename , #SQL = SQLStatement
FROM #SQLTbl
WHERE ISNULL(Execstatus ,0) = 0
IF #GenerateSQLOnly = 0
BEGIN
IF OBJECT_ID('SearchTMP','U') IS NOT NULL
DROP TABLE SearchTMP
EXEC (#SQL)
IF EXISTS(SELECT 1 FROM SearchTMP)
BEGIN
SELECT Tablename=#tmpTblname,* FROM SearchTMP
SELECT #MatchFound = 1
END
END
ELSE
BEGIN
PRINT REPLICATE('-',100)
PRINT #tmpTblname
PRINT REPLICATE('-',100)
PRINT replace(#SQL,'INTO SearchTMP','')
END
UPDATE #SQLTbl
SET Execstatus = 1
WHERE Tablename = #tmpTblname
END
IF #MatchFound = 0
BEGIN
SELECT #ErrMsg = 'No Matches are found in this database ' + DB_NAME() + ' for the specified filter'
PRINT #ErrMsg
RETURN
END
SET NOCOUNT OFF
Sorry in advance with the weird formatting, I can't put it more readable. I hope it helps someone. I also want to give credit to the onwer of the original stored procedure in here.
That stored procedure you linked to already has logic to check the table names in the database and populates a table variable with a list of tables to check. Just change this logic to Select from your ENUM_TABLES table instead. This could be based on an input parameter of #Id if you like...
In simple terms:
Remove the parameter #TableNames from the stored procedure
(optionally) replace the parameter with #ENUM_TABLE_ID or something
Change code in SP that looks like this:
IF LTRIM(RTRIM(#Tablenames)) = ''
/* Removed a load of lines looking at #TableNames...... */
....
SELECT #TblSQL = 'SELECT SCh.NAME,T.NAME
FROM SYS.TABLES T
JOIN SYS.SCHEMAS SCh
ON SCh.SCHEMA_ID = T.SCHEMA_ID
JOIN (' + #TableParamSQL + ') tblsrc
ON T.name LIKE tblsrc.tblname
JOIN (' + #SchemaParamSQL + ') schemasrc
ON SCh.name LIKE schemasrc.SchemaName
With something more like this:
SELECT #TblSQL = 'SELECT SCh.NAME,T.NAME
FROM SYS.TABLES T
JOIN SYS.SCHEMAS SCh
ON SCh.SCHEMA_ID = T.SCHEMA_ID
INNER JOIN ENUM_TABLES et on
(et.TABLENAME=T.NAME)
and (et.Id='+#ENUM_TABLE_ID+')'
And then I think it'll do what you want (lookup the list of tables from another table, based on an ID passed into the stored procedure)
(apologies for the slightly weird formatting of the SQL above; for some reason the SO markdown processor really didn't like that stuff, but it is hopefully readable. If anyone wants to try to edit this to improve it, be my guest.)
I would like this to be the ultimate discussion on how to check if a table exists in SQL Server 2000/2005 using SQL Statements.
Here are two possible ways of doing it. Which one is the standard/best way of doing it?
First way:
IF EXISTS (SELECT 1
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE='BASE TABLE'
AND TABLE_NAME='mytablename')
SELECT 1 AS res ELSE SELECT 0 AS res;
Second way:
IF OBJECT_ID (N'mytablename', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
MySQL provides the simple
SHOW TABLES LIKE '%tablename%';
statement. I am looking for something similar.
For queries like this it is always best to use an INFORMATION_SCHEMA view. These views are (mostly) standard across many different databases and rarely change from version to version.
To check if a table exists use:
IF (EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'TheSchema'
AND TABLE_NAME = 'TheTable'))
BEGIN
--Do Stuff
END
Also note that if for any reason you need to check for a temporary table you can do this:
if OBJECT_ID('tempdb..#test') is not null
--- temp table exists
We always use the OBJECT_ID style for as long as I remember
IF OBJECT_ID('*objectName*', 'U') IS NOT NULL
Please see the below approaches,
Approach 1: Using INFORMATION_SCHEMA.TABLES view
We can write a query like below to check if a Customers Table exists in the current database.
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'Customers')
BEGIN
PRINT 'Table Exists'
END
Approach 2: Using OBJECT_ID() function
We can use OBJECT_ID() function like below to check if a Customers Table exists in the current database.
IF OBJECT_ID(N'dbo.Customers', N'U') IS NOT NULL
BEGIN
PRINT 'Table Exists'
END
Approach 3: Using sys.Objects Catalog View
We can use the Sys.Objects catalog view to check the existence of the Table as shown below:
IF EXISTS(SELECT 1 FROM sys.Objects WHERE Object_id = OBJECT_ID(N'dbo.Customers') AND Type = N'U')
BEGIN
PRINT 'Table Exists'
END
Approach 4: Using sys.Tables Catalog View
We can use the Sys.Tables catalog view to check the existence of the Table as shown below:
IF EXISTS(SELECT 1 FROM sys.Tables WHERE Name = N'Customers' AND Type = N'U')
BEGIN
PRINT 'Table Exists'
END
Approach 5: Avoid Using sys.sysobjects System table
We should avoid using sys.sysobjects System Table directly, direct access to it will be deprecated in some future versions of the Sql Server. As per Microsoft BOL link, Microsoft is suggesting to use the catalog views sys.objects/sys.tables instead of sys.sysobjects system table directly.
IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = N'Customers' AND xtype = N'U')
BEGIN
PRINT 'Table Exists'
END
referred from: http://sqlhints.com/2014/04/13/how-to-check-if-a-table-exists-in-sql-server/
Looking for a table on a different database:
if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
Just wanted to mention one situation where it would probably be a little easier to use the OBJECT_ID method. The INFORMATION_SCHEMA views are objects under each database-
The information schema views are defined in a special schema named
INFORMATION_SCHEMA. This schema is contained in each database.
https://msdn.microsoft.com/en-us/library/ms186778.aspx
Therefore all tables you access using
IF EXISTS (SELECT 1
FROM [database].INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE='BASE TABLE'
AND TABLE_NAME='mytablename')
SELECT 1 AS res ELSE SELECT 0 AS res;
will only reflect what is in [database]. If you wanted to check if tables in another database exist, without dynamically changing the [database] each time, OBJECT_ID will let you do this out of the box. Ex-
IF OBJECT_ID (N'db1.schema.table1', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
works just as well as
IF OBJECT_ID (N'db2.schema.table1', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
SQL SERVER 2016 Edit:
Starting with 2016, Microsoft simplified the ability to check for non-existent objects prior to dropping, by adding the if exists keywords to drop statements. For example,
drop table if exists mytablename
will do the same thing as OBJECT_ID / INFORMATION_SCHEMA wrappers, in 1 line of code.
https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/03/drop-if-exists-new-thing-in-sql-server-2016/
IF OBJECT_ID('mytablename') IS NOT NULL
Using the Information Schema is the SQL Standard way to do it, so it should be used by all databases that support it. See Approach 1 in this answer.
You can use below code
IF (OBJECT_ID('TableName') IS NOT NULL )
BEGIN
PRINT 'Table Exists'
END
ELSE
BEGIN
PRINT 'Table NOT Exists'
END
Or
IF (EXISTS (SELECT * FROM sys.tables WHERE [name] = 'TableName'))
BEGIN
PRINT 'Table Exists'
END
ELSE
BEGIN
PRINT 'Table NOT Exists'
END
IF EXISTS
(
SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[Mapping_APCToFANavigator]')
AND
type in (N'U')
)
BEGIN
-- Do whatever you need to here.
END
Here in the above code, the table name is Mapping_APCToFANavigator.
If you need to work on different databases:
DECLARE #Catalog VARCHAR(255)
SET #Catalog = 'MyDatabase'
DECLARE #Schema VARCHAR(255)
SET #Schema = 'dbo'
DECLARE #Table VARCHAR(255)
SET #Table = 'MyTable'
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_CATALOG = #Catalog
AND TABLE_SCHEMA = #Schema
AND TABLE_NAME = #Table))
BEGIN
--do stuff
END
I know it is an old question but I have found this possibility if you plan to call it often.
create procedure Table_Exists
#tbl varchar(50)
as
return (select count(*) from sysobjects where type = 'U' and name = #tbl)
go
Just adding here, for the benefit of developers and fellow DBAs
a script that receives #Tablename as a parameter
(which may or may not contain the schemaname) and returns the info below if the schema.table exists:
the_name object_id the_schema the_table the_type
[Facts].[FactBackOrder] 758293761 Facts FactBackOrder Table
I produced this script to be used inside other scripts every time I need to test whether or not a table or view exists, and when it does, get its object_id to be used for other purposes.
It raises an error when either you passed an empty string, wrong schema name or wrong table name.
this could be inside a procedure and return -1 for example.
As an example, I have a table called "Facts.FactBackOrder" in one of my Data Warehouse databases.
This is how I achieved this:
PRINT 'THE SERVER IS ' + ##SERVERNAME
--select db_name()
PRINT 'THE DATABASE IS ' + db_NAME()
PRINT ''
GO
SET NOCOUNT ON
GO
--===================================================================================
-- #TableName is the parameter
-- the object we want to deal with (it might be an indexed view or a table)
-- the schema might or might not be specified
-- when not specified it is DBO
--===================================================================================
DECLARE #TableName SYSNAME
SELECT #TableName = 'Facts.FactBackOrder'
--===================================================================================
--===================================================================================
DECLARE #Schema SYSNAME
DECLARE #I INT
DECLARE #Z INT
SELECT #TableName = LTRIM(RTRIM(#TableName))
SELECT #Z = LEN(#TableName)
IF (#Z = 0) BEGIN
RAISERROR('Invalid #Tablename passed.',16,1)
END
SELECT #I = CHARINDEX('.',#TableName )
--SELECT #TableName ,#I
IF #I > 0 BEGIN
--===================================================================================
-- a schema and table name have been passed
-- example Facts.FactBackOrder
-- #Schema = Fact
-- #TableName = FactBackOrder
--===================================================================================
SELECT #Schema = SUBSTRING(#TABLENAME,1,#I-1)
SELECT #TableName = SUBSTRING(#TABLENAME,#I+1,#Z-#I)
END
ELSE BEGIN
--===================================================================================
-- just a table name have been passed
-- so the schema will be dbo
-- example Orders
-- #Schema = dbo
-- #TableName = Orders
--===================================================================================
SELECT #Schema = 'DBO'
END
--===================================================================================
-- Check whether the #SchemaName is valid in the current database
--===================================================================================
IF NOT EXISTS ( SELECT * FROM INFORMATION_SCHEMA.SCHEMATA K WHERE K.[SCHEMA_NAME] = #Schema ) BEGIN
RAISERROR('Invalid Schema Name.',16,1)
END
--SELECT #Schema as [#Schema]
-- ,#TableName as [#TableName]
DECLARE #R1 TABLE (
THE_NAME SYSNAME
,THE_SCHEMA SYSNAME
,THE_TABLE SYSNAME
,OBJECT_ID INT
,THE_TYPE SYSNAME
,PRIMARY KEY CLUSTERED (THE_SCHEMA,THE_NAME)
)
;WITH RADHE_01 AS (
SELECT QUOTENAME(SCHEMA_NAME(O.schema_id)) + '.' + QUOTENAME(O.NAME) AS [the_name]
,the_schema=SCHEMA_NAME(O.schema_id)
,the_table=O.NAME
,object_id =o.object_id
,[the_type]= CASE WHEN O.TYPE = 'U' THEN 'Table' ELSE 'View' END
from sys.objects O
where O.is_ms_shipped = 0
AND O.TYPE IN ('U','V')
)
INSERT INTO #R1 (
THE_NAME
,THE_SCHEMA
,THE_TABLE
,OBJECT_ID
,THE_TYPE
)
SELECT the_name
,the_schema
,the_table
,object_id
,the_type
FROM RADHE_01
WHERE the_schema = #Schema
AND the_table = #TableName
IF (##ROWCOUNT = 0) BEGIN
RAISERROR('Invalid Table Name.',16,1)
END
ELSE BEGIN
SELECT THE_NAME
,THE_SCHEMA
,THE_TABLE
,OBJECT_ID
,THE_TYPE
FROM #R1
END
In SQL Server 2000 you can try:
IF EXISTS(SELECT 1 FROM sysobjects WHERE type = 'U' and name = 'MYTABLENAME')
BEGIN
SELECT 1 AS 'res'
END
IF EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'PutSchemaHere'
AND
TABLE_NAME = 'PutTableNameHere'
)
Something important to know for anybody who hasn't found their solution yet:
SQL server != MYSQL.
If you want to do it with MYSQL, it is quite simple
$sql = "SELECT 1 FROM `db_name`.`table_name` LIMIT 1;";
$result = mysql_query($sql);
if( $result == false )
echo "table DOES NOT EXIST";
else
echo "table exists";
Posting this here because it's the top hit at Google.
I've had some problems either with selecting from INFORMATIONAL_SCHEME and OBJECT_ID. I don't know if it's an issue of ODBC driver or something.. Queries from SQL management studio, both, were okay.
Here is the solution:
SELECT COUNT(*) FROM <yourTableNameHere>
So, if the query fails, there is, probably, no such table in the database (or you don't have access permissions to it).
The check is done by comparing the value (integer in my case) returned by SQL executor which deals with ODBC driver..
if (sqlexec(conectionHandle, 'SELECT COUNT(*) FROM myTable') == -1) {
// myTable doesn't exist..
}
IF EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE
TABLE_CATALOG = 'Database Name' and
TABLE_NAME = 'Table Name' and
TABLE_SCHEMA = 'Schema Name') -- Database and Schema name in where statement can be deleted
BEGIN
--TABLE EXISTS
END
ELSE BEGIN
--TABLE DOES NOT EXISTS
END
You can use this :
IF OBJECT_ID (N'dbo.T', N'U') IS NOT NULL
BEGIN
print 'deleted table';
drop table t
END
else
begin
print 'table not found'
end
Create table t (id int identity(1,1) not null, name varchar(30) not null, lastname varchar(25) null)
insert into t( name, lastname) values('john','doe');
insert into t( name, lastname) values('rose',NULL);
Select * from t
1 john doe
2 rose NULL
-- clean
drop table t
I think the following query works:
IF EXISTS (select * from sys.tables
WHERE name='mytablename' )
BEGIN
print 'table exists in the database'
END
IF EXISTS ( SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.TableName') AND OBJECTPROPERTY(id, N'IsUserTable') = 1 )
BEGIN
SELECT * FROM dbo.TableName;
END
GO
There is one more option to check if the table exists across databases
IF EXISTS(SELECT 1 FROM [change-to-your-database].SYS.TABLES WHERE NAME = 'change-to-your-table-name')
BEGIN
-- do whatever you want
END
If anyone is trying to do this same thing in linq to sql (or especially linqpad) turn on option to include system tables and views and do this code:
let oSchema = sys.Schemas.FirstOrDefault(s=>s.Name==a.schema )
where oSchema !=null
let o=oSchema!=null?sys.Objects.FirstOrDefault (o => o.Name==a.item && o.Schema_id==oSchema.Schema_id):null
where o!=null
given that you have an object with the name in a property called item, and the schema in a property called schema where the source variable name is a
select name from SysObjects where xType='U' and name like '%xxx%' order by name
If this is to be the 'ultimate' discussion, then it should be noted that Larry Leonard's script can query a remote server as well if the servers are linked.
if exists (select * from REMOTE_SERVER.MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
-- -- create procedure to check if a table exists
DELIMITER $$
DROP PROCEDURE IF EXISTS `checkIfTableExists`;
CREATE PROCEDURE checkIfTableExists(
IN databaseName CHAR(255),
IN tableName CHAR(255),
OUT boolExistsOrNot CHAR(40)
)
BEGIN
SELECT count(*) INTO boolExistsOrNot FROM information_schema.TABLES
WHERE (TABLE_SCHEMA = databaseName)
AND (TABLE_NAME = tableName);
END $$
DELIMITER ;
-- -- how to use : check if table migrations exists
CALL checkIfTableExists('muDbName', 'migrations', #output);
i taking here creating a view as example.
Because ALTER/CREATE commands can't be within BEGIN/END blocks. You need to test for existence and the drop it before doing a create
IF Object_ID('TestView') IS NOT NULL
DROP VIEW TestView
GO
CREATE VIEW TestView
as
. . .
GO
If you are woried about the permissions being lost you can script the GRANT statements as well and re-run those at the end.
You could wrap the create/alter into a string and do an EXEC - that might get ugly for large views
DECLARE #SQL as varchar(4000)
-- set to body of view
SET #SQL = 'SELECT X, Y, Z FROM TABLE'
IF Object_ID('TestView') IS NULL
SET #SQL = 'CREATE VIEW TestView AS ' + #SQL
ELSE
SET #SQL = 'ALTER VIEW TestView AS ' + #SQL
Run this query to check if the table exists in the database:
IF(SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'YourTableName') IS NOT NULL
PRINT 'Table Exists';
consider in one database you have a table t1. you want to run script on other Database like - if t1 exist then do nothing else create t1.
To do this open visual studio and do the following:
Right click on t1, then Script table as, then DROP and Create To, then New Query Editor
you will find your desired query. But before executing that script don't forget to comment out the drop statement in the query as you don't want to create new one if there is already one.
Thanks
I want to PassColumn name as a paremeter in My SP
And if my tat column exists in first table (Batch_Master), want to fatch value from that column,
And if that column exists in my second table (GTIN_Master), want to fetch value from tat table column,
Each table have columns like..
Batch_Master (Batch_M_id, GTIN(primary key),....etc
GTIN_Master (GTIN (foreign key),..etc)
I have Batch_M_id, and column name as a parameter..
Note: column Name having random datatype, some time int or some time datetime etc
I Try followin SP
CREATE PROCEDURE dbo.StoredProcedure2
#columnName varchar(50),
#batchmId int
AS
if exists(select * from sys.columns
where Name = N'columnName' and Object_ID = Object_ID(NBatch_Master'))
begin
select #columnName from Batch_Master
end
else
begin
select #columnName
from GTIN_Master inner join Batch_Master
on GTIN_Master.GTIN = Batch_Master.GTIN
where Batch_M_id =#batchmId
end
RETURN
What you need when you do not know exactly the query structure you are going to execute, then you have to create a dynamic query, which is actually a form of templating queries.
CREATE PROCEDURE dbo.StoredProcedure2
#columnName varchar(50),
#batchmId int
AS
DECLARE #SQL1 AS VARCHAR(MAX)
DECLARE #SQL2 AS VARCHAR(MAX)
SET #SQL1 = 'select ' + #columnName + ' from Batch_Master'
SET #SQL1 = 'select ' + #columnName + '
from GTIN_Master inner join Batch_Master
on GTIN_Master.GTIN = Batch_Master.GTIN
where Batch_M_id =' + CONVERT(VARCHAR,#batchmId)
IF EXISTS(SELECT * FROM sys.columns WHERE Name = #columnName and Object_ID = Object_ID(N'Batch_Master'))
BEGIN
EXEC (#SQL1)
END
ELSE
BEGIN
EXEC (#SQL2)
END
The above will do what you want but is prone to errors. For instance what if the column passed in the parameter does not exist in the tables used in the second query? You should probably need to check for existence in the second case too.
DECLARE #SQL VARCHAR(MAX)
SET #SQL = 'select ' + #columnName + ' from Batch_Master'
EXECUTE(#SQL)
This SQL:
set nocount on
go
create table One (id int, name varchar(25))
go
create table Two (id int, value varchar(25))
go
insert into One values (1, 'Table One')
insert into Two values (1, 'Table Two')
go
create procedure sp_test_colname
#colname sysname
as
declare #sql nvarchar(2048)
if exists (select 1 from sys.columns where name = #colname and object_id = object_id(N'One'))
set #sql = 'select [' + #colname + '] from [One]'
else
if exists (select 1 from sys.columns where name = #colname and object_id = object_id(N'Two'))
set #sql = 'select [' + #colname + '] from [Two]'
if #sql <> ''
exec sp_executesql #sql
go
exec sp_test_colname 'name'
exec sp_test_colname 'value'
exec sp_test_colname 'somethingelse'
go
drop procedure sp_test_colname
drop table One, Two
Returns the following:
name
-------------------------
Table One
value
-------------------------
Table Two
How to delete all rows from all tables in a SQL Server database?
Note that TRUNCATE won't work if you have any referential integrity set.
In that case, this will work:
EXEC sp_MSForEachTable 'DISABLE TRIGGER ALL ON ?'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'ENABLE TRIGGER ALL ON ?'
GO
Edit: To be clear, the ? in the statements is a ?. It's replaced with the table name by the sp_MSForEachTable procedure.
In my recent project my task was to clean an entire database by using sql statement and each table having many constraints like Primary Key and Foreign Key. There are more than 1000 tables in database so its not possible to write a delete query on each and ever table.
By using a stored procedure named sp_MSForEachTable which allows us to easily process some code against each and every table in a single database. It means that it is used to process a single T-SQL command or a different T-SQL commands against every table in the database.
So follow the below steps to truncate all tables in a SQL Server Database:
Step 1- Disable all constraints on the database by using below sql query :
EXEC sys.sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
Step 2- Execute a Delete or truncate operation on each table of the database by using below sql command :
EXEC sys.sp_msforeachtable 'DELETE FROM ?'
Step 3- Enable all constraints on the database by using below sql statement:
EXEC sys.sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
I had to delete all the rows and did it with the next script:
DECLARE #Nombre NVARCHAR(MAX);
DECLARE curso CURSOR FAST_FORWARD
FOR
Select Object_name(object_id) AS Nombre from sys.objects where type = 'U'
OPEN curso
FETCH NEXT FROM curso INTO #Nombre
WHILE (##FETCH_STATUS <> -1)
BEGIN
IF (##FETCH_STATUS <> -2)
BEGIN
DECLARE #statement NVARCHAR(200);
SET #statement = 'DELETE FROM ' + #Nombre;
print #statement
execute sp_executesql #statement;
END
FETCH NEXT FROM curso INTO #Nombre
END
CLOSE curso
DEALLOCATE curso
Hope this helps!
In my case, I needed to set QUOTED_IDENTIFIER on. This led to a slight modification of Mark Rendle's answer above:
EXEC sp_MSforeachtable 'DISABLE TRIGGER ALL ON ?'
GO
EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
GO
EXEC sp_MSforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
GO
EXEC sp_MSforeachtable 'ENABLE TRIGGER ALL ON ?'
GO
Here is a solution that:
Drops constraints (thanks to this post)
Iterates through INFORMATION_SCHEMA.TABLES for a particular database
SELECTS tables based on some search criteria
Deletes all the data from those tables
Re-adds constraints
Allows for ignoring of certain tables such as sysdiagrams and __RefactorLog
I initially tried EXECUTE sp_MSforeachtable 'TRUNCATE TABLE ?', but that deleted my diagrams.
USE <DB name>;
GO
-- Disable all constraints in the database
EXEC sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
declare #catalog nvarchar(250);
declare #schema nvarchar(250);
declare #tbl nvarchar(250);
DECLARE i CURSOR LOCAL FAST_FORWARD FOR select
TABLE_CATALOG,
TABLE_SCHEMA,
TABLE_NAME
from INFORMATION_SCHEMA.TABLES
where
TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME != 'sysdiagrams'
AND TABLE_NAME != '__RefactorLog'
OPEN i;
FETCH NEXT FROM i INTO #catalog, #schema, #tbl;
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #sql NVARCHAR(MAX) = N'DELETE FROM [' + #catalog + '].[' + #schema + '].[' + #tbl + '];'
/* Make sure these are the commands you want to execute before executing */
PRINT 'Executing statement: ' + #sql
-- EXECUTE sp_executesql #sql
FETCH NEXT FROM i INTO #catalog, #schema, #tbl;
END
CLOSE i;
DEALLOCATE i;
-- Re-enable all constraints again
EXEC sp_MSforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
Set nocount on
Exec sp_MSforeachtable 'Alter Table ? NoCheck Constraint All'
Exec sp_MSforeachtable
'
If ObjectProperty(Object_ID(''?''), ''TableHasForeignRef'')=1
Begin
-- Just to know what all table used delete syntax.
Print ''Delete from '' + ''?''
Delete From ?
End
Else
Begin
-- Just to know what all table used Truncate syntax.
Print ''Truncate Table '' + ''?''
Truncate Table ?
End
'
Exec sp_MSforeachtable 'Alter Table ? Check Constraint All'
If you just have constraints just paste this lines in the query and run it
EXEC sys.sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sys.sp_msforeachtable 'DELETE FROM ?'
EXEC sys.sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
You could delete all the rows from all tables using an approach like Rubens suggested, or you could just drop and recreate all the tables. Always a good idea to have the full db creation scripts anyway so that may be the easiest/quickest method.
This answer builds on Zach Smith's answer by resetting the identity column as well:
Disabling all constraints
Iterating through all tables except those you choose to exclude
Deletes all rows from the table
Resets the identity column if one exists
Re-enables all constraints
Here is the query:
-- Disable all constraints in the database
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
declare #catalog nvarchar(250);
declare #schema nvarchar(250);
declare #tbl nvarchar(250);
DECLARE i CURSOR LOCAL FAST_FORWARD FOR select
TABLE_CATALOG,
TABLE_SCHEMA,
TABLE_NAME
from INFORMATION_SCHEMA.TABLES
where
TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME != 'sysdiagrams'
AND TABLE_NAME != '__RefactorLog'
-- Optional
-- AND (TABLE_SCHEMA = 'dbo')
OPEN i;
FETCH NEXT FROM i INTO #catalog, #schema, #tbl;
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #sql NVARCHAR(MAX) = N'DELETE FROM [' + #catalog + '].[' + #schema + '].[' + #tbl + '];'
/* Make sure these are the commands you want to execute before executing */
PRINT 'Executing statement: ' + #sql
--EXECUTE sp_executesql #sql
-- Reset identity counter if one exists
IF ((SELECT OBJECTPROPERTY( OBJECT_ID(#catalog + '.' + #schema + '.' + #tbl), 'TableHasIdentity')) = 1)
BEGIN
SET #sql = N'DBCC CHECKIDENT ([' + #catalog + '.' + #schema + '.' + #tbl + '], RESEED, 0)'
PRINT 'Executing statement: ' + #sql
--EXECUTE sp_executesql #sql
END
FETCH NEXT FROM i INTO #catalog, #schema, #tbl;
END
CLOSE i;
DEALLOCATE i;
-- Re-enable all constraints again
EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
For some requirements we might have to skip certain tables. I wrote the below script to add some extra conditions to filter the list of tables. The below script will also display the pre delete count and post delete count.
IF OBJECT_ID('TEMPDB..#TEMPRECORDCOUNT') IS NOT NULL
DROP TABLE #TEMPRECORDCOUNT
CREATE TABLE #TEMPRECORDCOUNT
( TABLENAME NVARCHAR(128)
,PREDELETECOUNT BIGINT
,POSTDELETECOUNT BIGINT
)
INSERT INTO #TEMPRECORDCOUNT (TABLENAME, PREDELETECOUNT, POSTDELETECOUNT)
SELECT O.name TableName
,DDPS.ROW_COUNT PREDELETECOUNT
,NULL FROM sys.objects O
INNER JOIN (
SELECT OBJECT_ID, SUM(row_count) ROW_COUNT
FROM SYS.DM_DB_PARTITION_STATS
GROUP BY OBJECT_ID
) DDPS ON DDPS.OBJECT_ID = O.OBJECT_ID
WHERE O.type = 'U' AND O.name NOT LIKE 'OC%' AND O.schema_id = 1
DECLARE #TableName NVARCHAR(MAX);
DECLARE TableDeleteCursor CURSOR FAST_FORWARD
FOR
SELECT TableName from #TEMPRECORDCOUNT
OPEN TableDeleteCursor
FETCH NEXT FROM TableDeleteCursor INTO #TableName
WHILE (##FETCH_STATUS <> -1)
BEGIN
IF (##FETCH_STATUS <> -2)
BEGIN
DECLARE #STATEMENT NVARCHAR(MAX);
SET #STATEMENT = ' DISABLE TRIGGER ALL ON ' + #TableName +
'; ALTER TABLE ' + #TableName + ' NOCHECK CONSTRAINT ALL' +
'; DELETE FROM ' + #TableName +
'; ALTER TABLE ' + #TableName + ' CHECK CONSTRAINT ALL' +
'; ENABLE TRIGGER ALL ON ' + #TableName;
PRINT #STATEMENT
EXECUTE SP_EXECUTESQL #STATEMENT;
END
FETCH NEXT FROM TableDeleteCursor INTO #TableName
END
CLOSE TableDeleteCursor
DEALLOCATE TableDeleteCursor
UPDATE T
SET T.POSTDELETECOUNT = I.ROW_COUNT
FROM #TEMPRECORDCOUNT T
INNER JOIN (
SELECT O.name TableName, DDPS.ROW_COUNT ROW_COUNT
FROM sys.objects O
INNER JOIN (
SELECT OBJECT_ID, SUM(row_count) ROW_COUNT
FROM SYS.DM_DB_PARTITION_STATS
GROUP BY OBJECT_ID
) DDPS ON DDPS.OBJECT_ID = O.OBJECT_ID
WHERE O.type = 'U' AND O.name NOT LIKE 'OC%' AND O.schema_id = 1
) I ON I.TableName COLLATE DATABASE_DEFAULT = T.TABLENAME
SELECT * FROM #TEMPRECORDCOUNT
ORDER BY TABLENAME ASC
--Load tables to delete from
SELECT
DISTINCT
' Delete top 1000000 from <DBName>.<schema>.' + c.TABLE_NAME + ' WHERE <Filter Clause Here>' AS query,c.TABLE_NAME AS TableName, IsDeleted=0, '<InsertSomeDescriptorHere>' AS [Source]--,t.TABLE_TYPE, c.*
INTO dbo.AllTablesToDeleteFrom
FROM INFORMATION_SCHEMA.TABLES AS t
INNER JOIN information_schema.columns c ON c.TABLE_NAME = t.TABLE_NAME
WHERE c.COLUMN_NAME = '<column name>'
AND c.TABLE_SCHEMA = 'dbo'
AND c.TABLE_CATALOG = '<DB Name here>'
AND t.TABLE_TYPE='Base table'
--AND t.TABLE_NAME LIKE '<put filter here>'
DECLARE #TableSelect NVARCHAR(1000)= '';
DECLARE #Table NVARCHAR(1000)= '';
DECLARE #IsDeleted INT= 0;
DECLARE #NumRows INT = 1000000;
DECLARE #Source NVARCHAR(50)='';
WHILE ( #IsDeleted = 0 )
BEGIN
--This grabs one table at a time to be deleted from. #TableSelect has the sql to execute. it is important to order by IsDeleted ASC
--because it will pull tables to delete from by those that have a 0=IsDeleted first. Once the loop grabs a table with IsDeleted=1 then this will pop out of loop
SELECT TOP 1
#TableSelect = query,
#IsDeleted = IsDeleted,
#Table = TableName,
#Source=[a].[Source]
FROM dbo.AllTablesToDeleteFrom a
WHERE a.[Source]='SomeDescriptorHere'--use only if needed
ORDER BY a.IsDeleted ASC;--this is required because only those records returned with IsDeleted=0 will run through loop
--SELECT #Table; can add this in to monitor what table is being deleted from
WHILE ( #NumRows = 1000000 )--only delete a million rows at a time?
BEGIN
EXEC sp_executesql #TableSelect;
SET #NumRows = ##ROWCOUNT;
--IF #NumRows = 1000000 --can do something here if needed
--One wants this loop to continue as long as a million rows is deleted. Once < 1 million rows is deleted it pops out of loop
--and grabs next table to delete
-- BEGIN
--SELECT #NumRows;--can add this in to see current number of deleted records for table
INSERT INTO dbo.DeleteFromAllTables
( tableName,
query,
cnt,
[Source]
)
SELECT #Table,
#TableSelect,
#NumRows,
#Source;
-- END;
END;
SET #NumRows = 1000000;
UPDATE a
SET a.IsDeleted = 1
FROM dbo.AllTablesToDeleteFrom a
WHERE a.TableName = #Table;
--flag this as deleted so you can move on to the next table to delete from
END;
if you want to delete the whole table, you must follow the next SQL instruction
Delete FROM TABLE Where PRIMARY_KEY_ is Not NULL;