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 have a DB with 60 tables. In some of those tables I have a bit column named "Open" where I store a 0 if the record is not in use by an user (user access DB from a C# application) and an 1 if the record is in use.
Well, I need to get all the records from all the tables in my database where the "open" column value is true, or 1.
Is this even possible to do?
Here's a simple use of the undocumented sp_MSforeachtable:
EXEC sp_MSforeachtable
#command1='SELECT * FROM ? WHERE Open=1',
#whereand='AND o.id in (select object_id from sys.columns c where c.name=''Open'')'
Quick piece of code that gets list of tables within your database. Using a cursor loop through the answers checking it they have the fld named [open] and if it does the build a SQL statement and the execute this SQL string.
CREATE PROCEDURE usp_BulkTableOpenReport
AS
BEGIN
DECLARE #TBLS AS TABLE (REF INT IDENTITY (0,1), TABLENAME NVARCHAR(100), TABLEID BIGINT);
DECLARE #TBL AS NVARCHAR(100);
DECLARE #TBLID AS BIGINT;
DECLARE #SQL AS NVARCHAR(MAX);
DECLARE #I INT = 0;
DECLARE #M INT = 0;
DECLARE #V INT = 0
INSERT INTO #TBLS(TABLENAME,TABLEID)
SELECT NAME,OBJECT_ID FROM sys.tables
SELECT #M = MAX(REF) FROM #TBLS
WHILE #I <= #M
BEGIN
SELECT #TBL = TABLENAME, #TBLID= TABLEID FROM #TBLS WHERE REF = #I
/* CHECK TO MAKE INSURE THAT A FLD CALLED [OPEN] EXIST. */
SELECT #V = COUNT(*) FROM SYS.columns WHERE name = 'OPEN' AND OBJECT_ID = #TBLID
IF #V != 0
BEGIN
SET #SQL = 'SELECT * FROM [' + #TBL + '] WHERE [OPEN] = 1'
EXEC SP_EXECUTESQL #SQL
END;
SET #I = #I + 1
END;
END
GO
From your c# application exec the query "EXEC usp_BulkTableOpenReport" then loop through the table outputs.
I am using Silverlight and Linq-to-SQL to communicate with the database.
I have a stored procedure which receives 2 parameters (PFOID and Quantity) and Userid and returns a product name.
If we send multiple values like multiple pfoid's and quantity's it will return multiple product names shown as below
The stored procedure looks like this..
ALTER PROCEDURE [PFO].[PFOValidateUpdateData]
#PfoIDs xml, -- list of PFO ID's
#UserID uniqueidentifier --The Identity of the User making the call.
AS
BEGIN
-- SET DEFAULT BEHAVIOR
SET NOCOUNT ON -- Performance: stops rows affected messages
SET DEADLOCK_PRIORITY LOW -- This SP to be the Deadlock victim
-- Initialise Lock-Timeout and Deadlock vars for Insert
DECLARE #iLockTimeoutRetries as int
DECLARE #iDeadLockRetries as int
DECLARE #dtLockTimeoutSleepInterval as datetime
DECLARE #dtDeadlockSleepInterval as datetime
DECLARE #iErrorNumber as int
SET #iLockTimeoutRetries = 0
SET #iDeadLockRetries = 0
SET #dtLockTimeoutSleepInterval = sCommon.fnLockTimeoutSleepInterval()
SET #dtDeadlockSleepInterval= sCommon.fnDeadlockSleepInterval()
SET #iErrorNumber = 0
-- procedure specific
DECLARE #idoc as int
DECLARE #IsBrightstarUser as bit
RETRY:
BEGIN TRY
--Create Temp table to store stores!
CREATE TABLE [#PFOList]
(
[PFOId] nvarchar(50),
[Quantity] INT
)
--Create Temp table to store User stores!
CREATE TABLE [#UserStoreList]
(
[StoreID_XRef] nvarchar(50)
)
print CONVERT(varchar(1000), #PfoIDs)
--Create Document
EXEC sp_xml_preparedocument #idoc OUTPUT, #PfoIDs
-- Append to new list of Store records
INSERT INTO [#PFOList] (
[PFOId],
[Quantity]
)
SELECT [PFOID],[Quantity]
FROM OPENXML (#idoc, 'ArrayOfString/string',2)
WITH( [PFOID] nvarchar(50),[Quantity] [INT]) Stores
--WHERE [PFOId] Is Not NULL
-- Clean UP
exec sp_xml_removedocument #iDoc
-- are we dealing with a brightstar user?
SET #IsBrightstarUser = CASE WHEN exists
(SELECT *
FROM dbo.aspnet_UsersInRoles AS uir inner join
dbo.aspnet_Roles AS roles ON uir.RoleId = roles.roleid
WHERE roles.rolename = 'Brightstar Employee' and uir.userid = #userid)
THEN 1 ELSE 0 END
--Get User Storelist
INSERT INTO [#UserStoreList] (
[StoreID_XRef]
)
SELECT s.StoreId_XRef
FROM PFO.UserStoreLink us(nolock)
INNER JOIN PFO.Store s(nolock)
ON us.StoreId=s.StoreId
where UserId=#UserID
--Select * from [#PFOList]
--SELECT #IsBrightstarUser AS ISBrightstaruser
--SELECT * from [#UserStoreList]
--If BrightstarCustomer Update all the Quantities.
IF #IsBrightstarUser=1
BEGIN
UPDATE
PFO.PFO
SET
IsBrightstarReviewComplete = 1
,[ModifyingUsersID] = #UserID
,[ModifiedDate] = getdate()
,[PlannedQty] = pfol.[Quantity]
,[BrightstarReviewedQty]=pfol.[Quantity]
FROM
PFO.PFO as pfo
INNER JOIN [#UserStoreList] as stores on pfo.StoreId_XRef=stores.StoreID_XRef
INNER JOIN [#PFOList] as pfol on pfo.PFOId = pfol.PFOId
WHERE #IsBrightstarUser = 1
END
ELSE BEGIN
--Update Non Contrained Orders
UPDATE
PFO.PFO
SET
[ModifyingUsersID] = #UserID
,[ModifiedDate] = getdate()
,[PlannedQty] = pfol.[Quantity]
FROM
PFO.PFO (nolock) as pfo
INNER JOIN [#UserStoreList] as stores on pfo.StoreId_XRef=stores.StoreID_XRef
INNER JOIN [#PFOList] as pfol on pfo.PFOId = pfol.PFOId
WHERE pfo.IsBrightstarReviewComplete=1 AND IsConstraint=0
--SELECT * from PFO.PFO (nolock) where PFOId='04676723-2afb-49ff-9fa1-0131cabb407c'
--Update Contrained Orders
--Get Existing quantities for the User
CREATE TABLE #ExistingProductQuantity
(
[PfoID] nvarchar(100)
,[Product] nvarchar(255)
,[PlannedQty] INT
,[BrightstarReviewedQty] INT
)
CREATE TABLE #CustProductQuantity
(
[Product] nvarchar(255)
,[IsUpdatable] BIT
)
INSERT INTO #ExistingProductQuantity
( [PfoID],[Product],[PlannedQty],[BrightstarReviewedQty])
SELECT PFOId,InventoryId,PlannedQty,BrightstarReviewedQty
FROM PFO.PFO as pfo
INNER JOIN [#UserStoreList] as stores on pfo.StoreId_XRef=stores.StoreID_XRef
WHERE pfo.IsBrightstarReviewComplete=1 AND IsConstraint=1
UPDATE
#ExistingProductQuantity
SET [PlannedQty]=pfol.[Quantity]
FROM #ExistingProductQuantity eoq
INNER JOIN [#PFOList] as pfol on eoq.PFOId = pfol.PFOId
INSERT INTO #CustProductQuantity
( [Product],[IsUpdatable] )
SELECT
[Product],
CASE WHEN SUM(PlannedQty)<=SUM(BrightstarReviewedQty) THEN 1 ELSE 0 END
FROM #ExistingProductQuantity
GROUP BY [Product]
--SELECT * from #ExistingProductQuantity
--SELECT * from #CustProductQuantity
--Update the products that can be updatable
UPDATE
PFO.PFO
SET
[ModifyingUsersID] = #UserID
,[ModifiedDate] = getdate()
,[PlannedQty] = pfol.[Quantity]
FROM
PFO.PFO as pfo
INNER JOIN #UserStoreList as stores on pfo.StoreId_XRef=stores.StoreID_XRef
INNER JOIN #PFOList as pfol on pfo.PFOId = pfol.PFOId
INNER JOIN #CustProductQuantity as pr on pr.Product=pfo.InventoryId
WHERE pfo.IsBrightstarReviewComplete=1 AND pr.IsUpdatable=1 AND IsConstraint=1
--Return the products that are not updatabele
select [Product]
FROM #CustProductQuantity
where [IsUpdatable]=0
END
END TRY
BEGIN CATCH
-- Get the ErrorNumber
Set #iErrorNumber = ERROR_NUMBER()
--Handle Deadlock situation (Deletes, Inserts & Updates)
IF #iErrorNumber = 1205
BEGIN
-- If we have not made enough attempts to break the lock
IF #iDeadLockRetries < sCommon.fnMaxDeadlockRetries()
BEGIN
-- Increment the Attempt count
SET #iDeadLockRetries = #iDeadLockRetries + 1
-- Pause to allow the deadlock contention to clear
WAITFOR DELAY #dtDeadlockSleepInterval
GOTO RETRY
END
END
-- Handle Lock Timeout situation (Deletes, Inserts & Updates)
IF #iErrorNumber = 1222
BEGIN
-- If we have not made enough attempts to break the Deadlock
IF #iLockTimeoutRetries < sCommon.fnMaxLockTimeoutRetries()
BEGIN
-- Increment the Attempt count
SET #iLockTimeoutRetries = #iLockTimeoutRetries + 1
-- Pause to allow the lock contention to clear
WAITFOR DELAY #dtLockTimeoutSleepInterval
GOTO RETRY
END
END
exec Common.RethrowError
END CATCH
END
The result is as follows..
Product
6435LVWK-360-CD819E3
NSCHI535C1097I360-4C
NSCHU485C1819I360-0C
Return Value
0
My Linq-to-SQL connection is like this
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="PFO.PFOValidateUpdateData")]
public int PFOValidateUpdateData([global::System.Data.Linq.Mapping.ParameterAttribute(Name = "PfoIDs", DbType = "Xml")] System.Xml.Linq.XElement pfoIDs, [global::System.Data.Linq.Mapping.ParameterAttribute(Name = "UserID", DbType = "UniqueIdentifier")] System.Nullable<System.Guid> userID)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), pfoIDs, userID);
return ((int)(result.ReturnValue));
}
I am trying to retrieve all the data from the stored procedure but the when I debugging it the return value is "o"..
I would be grateful to you if you could help me retrieve all the data returned by the stored procedure... thank you very much...
If your stored procedure returns a collection of nvarchar's, then the signature of your Linq2Sql method is not correct. It should not return an int, but an ISingleResult.
So the correct signature will be:
public ISingleResult<string> PFOValidateUpdateData(...)
{
IExecuteResult result = this....;
return (ISingleResult<string>)result.ReturnValue;
}
var products = PFOValidateUpdateData(...).ToList();
If you want to return the results from multiple SELECT's in your stored procedure, you'll have to use IMultipleResults.
Well I know this is not the right way...for time being,its working for me...
I created an other table with two columns one ProductId and ID, I am inserting the values returned by the stored procedure,
in the designer.cs I am returning the table,
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="PFO.PFOValidateUpdateData")]
public ISingleResult<PFOValidData> PFOValidateUpdateData([global::System.Data.Linq.Mapping.ParameterAttribute(Name = "PfoIDs", DbType = "Xml")] System.Xml.Linq.XElement pfoIDs, [global::System.Data.Linq.Mapping.ParameterAttribute(Name = "UserID", DbType = "UniqueIdentifier")] System.Nullable<System.Guid> userID)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), pfoIDs, userID);
return ((ISingleResult<PFOValidData>)(result.ReturnValue));
}
And in the Domainservice
List<string> PFOValidateUpdateData(string pfoIds, Guid userID)
{
List<string> productIdList = new List<string>();
// Acquire the int
result = this.DataContext.PFOValidateUpdateData(element, userID);
foreach (var item in result)
{
productIdList.Add(item.ProductID);
}
return productIdList;
To get the multiple values returned by the stored procedure....
Please let me know if there is a better way to solve this... thank you
I have a table DEPT, which holds 2 columns - ID, NAME.
A search form is presented with the IDs from the DEPT table and the user can chose any number of IDs and submit the form, to get the related NAMEs.
Clarification/Inputs:
I don't want to build a dynamic query - its not manageable.
I prefer a stored procedure using table-valued parameters
Any other solutions to proceed?
NOTE:
This example is simple with 1 table - in real life, I have to deal with more than 6 tables!
Thanks for any suggestions
CREATE TYPE dbo.DeptList
AS TABLE
(
ID INT
);
GO
CREATE PROCEDURE dbo.RetrieveDepartments
#dept_list AS dbo.DeptList READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT Name FROM dbo.table1 WHERE ID IN (SELECT ID FROM #dept)
UNION ALL
SELECT Name FROM dbo.table2 WHERE ID IN (SELECT ID FROM #dept)
-- ...
END
GO
Now in your C# code, create a DataTable, fill it in with the IDs, and pass it in to the stored procedure. Assuming you already have a list called tempList and the IDs are stored in id:
DataTable tvp = new DataTable();
tvp.Columns.Add(new DataColumn("ID"));
foreach(var item in tempList)
{
tvp.Rows.Add(item.id);
}
using (connObject)
{
SqlCommand cmd = new SqlCommand("StoredProcedure", connObject);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvparam = cmd.Parameters.AddWithValue("#dept_list", tvp);
tvparam.SqlDbType = SqlDbType.Structured;
...
}
You can also use a split function. Many exist, this is the one I like if you can guarantee that the input is safe (no <, >, & etc.):
CREATE FUNCTION dbo.SplitInts_XML
(
#List VARCHAR(MAX),
#Delimiter CHAR(1)
)
RETURNS TABLE
AS
RETURN
(
SELECT Item = y.i.value('(./text())[1]', 'int')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(#List, #Delimiter, '</i><i>') + '</i>').query('.')
) AS a
CROSS APPLY x.nodes('i') AS y(i)
);
GO
Now your procedure can be:
CREATE PROCEDURE dbo.RetrieveDepartments
#dept_list VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
;WITH d AS (SELECT ID = Item FROM dbo.SplitInts(#dept_list, ','))
SELECT Name FROM dbo.table1 WHERE ID IN (SELECT ID FROM d)
UNION ALL
SELECT Name FROM dbo.table2 WHERE ID IN (SELECT ID FROM d)
-- ...
END
GO