dynamic cursor in stored procedure - c#

hi i am dojng a stored procedure which conatains a cursor...cursor has a dynamic sql query ..this query has dynamic value..which is #industry..then i put the results in a temporary table..but the problem is when i execute the procedure results are not coming...
this is my stroedproc in sqlserver
ALTER PROCEDURE GETARTISTDETAIL AS
BEGIN
DECLARE #INDUSTRY VARCHAR(40)
DECLARE #ID INT
DECLARE #SQL1 VARCHAR(1000)
DECLARE #SQL VARCHAR(1000)
SET #INDUSTRY='''BollyWood'',''TollyWood'',''HollyWood'''
CREATE TABLE #TEMPTBL([NAME] VARCHAR(20),[AGE] INT ,[MAILID] VARCHAR(20))
--SET #SQL='SELECT ARTISTID FROM ARTIST WHERE INDUSTRY IN ('+#INDUSTRY+')'
DECLARE TEMPCRS CURSOR LOCAL SCROLL STATIC FOR SELECT ARTISTID FROM ARTIST WHERE INDUSTRY IN (#INDUSTRY)
--PRINT #SQL
--exec (#SQL)
OPEN TEMPCRS
FETCH NEXT FROM TEMPCRS INTO #ID
WHILE ##FETCH_STATUS=0
BEGIN
INSERT INTO #TEMPTBL SELECT [NAME],[AGE],[MAILID] FROM ARTIST WHERE ARTISTID=#ID
FETCH NEXT FROM TEMPCRS INTO #ID
END
CLOSE TEMPCRS
DEALLOCATE TEMPCRS
SELECT * FROM #TEMPTBL
DROP TABLE #TEMPTBL
END

You don't need a cursor to do this, just use a subquery:
DECLARE #INDUSTRY VARCHAR(40)
DECLARE #SQL VARCHAR(1000)
CREATE TABLE #TEMPTBL([NAME] VARCHAR(20),[AGE] INT ,[MAILID] VARCHAR(20))
SET #INDUSTRY='''BollyWood'',''TollyWood'',''HollyWood'''
SET #SQL='INSERT INTO #TEMPTBL SELECT [NAME],[AGE],[MAILID]
FROM ARTIST WHERE ARTISTID IN (
SELECT ARTISTID FROM ARTIST WHERE INDUSTRY IN ('+#INDUSTRY+')
)'
EXEC (#SQL)
SELECT * FROM #TEMPTBL
DROP TABLE #TEMPTBL

Related

Get SQL Cursor Fetched Data in list of Asp.net MVC

I have multiple queries in nested for each loop with millions of records its tack long to process queries with each iteration of loop from asp.net MVC then I have create a cursor instead of executing multiple queries from the action but can't retrieve fetched rows in list/variable.
SQL:
ALTER proc [dbo].[sp_get_AllofPostings]
#comp nvarchar(max),
#TNumber int
as
begin
DECLARE #Id NVARCHAR(128), #AccountCode varchar(max), #TrasactionNumber int, #LedgerNumber int, #RefCode varchar(50), #IsDebit bit, #Amount float, #pcomp nvarchar(max), #CreateDate datetime, #status bit
-- declare cursor
DECLARE postings_cursor CURSOR FOR
SELECT * FROM Postings where TrasactionNumber = #TNumber and CoId=#comp and Amount IS NOT NULL
OPEN postings_cursor;
FETCH NEXT FROM postings_cursor INTO #Id, #AccountCode, #TrasactionNumber, #LedgerNumber, #RefCode, #IsDebit, #Amount, #pcomp, #CreateDate, #status
WHILE ##FETCH_STATUS = 0
BEGIN
--do somthing here
Declare #LAccountName nvarchar(max), #LGLAccount int, #GLName nvarchar(max), #Gaccountcode varchar(50)
SET #LAccountName = (select AccountName from Ledgers where CoId=#comp and AccountCode=#AccountCode)
SET #LGLAccount = (select GLAccount from Ledgers where CoId=#comp and AccountCode=#AccountCode)
SET #GLName = (select GLName from GLAccounts where CoId=#comp and Keyid = #LGLAccount)
SET #Gaccountcode = (select Name from Groups where CoId=#comp and Code = #AccountCode)
FETCH NEXT FROM postings_cursor INTO #Id, #AccountCode, #TrasactionNumber, #LedgerNumber, #RefCode, #IsDebit, #Amount, #pcomp, #CreateDate, #status
END;
CLOSE postings_cursor;
DEALLOCATE postings_cursor;
END
C#:
var posting = db.sp_get_AllofPostings(comp, item.Number);

Fire trigger with cursor using Bulk Insert

I am using BulkInsert - works fine - and trigger - works fine - with cursor which is not working I think. Would you please look at my code and tell me what is my mistake?
Thank you very much.
ALTER TRIGGER [dbo].[CheckProducts]
ON [dbo].[ProductsTemp]
AFTER INSERT
AS
BEGIN
DECLARE #Name NVARCHAR(MAX);
DECLARE #Manufacturer NVARCHAR(MAX);
DECLARE #Source NVARCHAR(50);
DECLARE #SOurceDetailUrl NVARCHAR(MAX);
DECLARE #MainPrice DECIMAL;
DECLARE #SalesPrice DECIMAL;
DECLARE #Description NVARCHAR(MAX);
DECLARE #ImageUrl NVARCHAR(MAX);
DECLARE #GroupId INT;
DECLARE #ParentCategoryId INT;
DECLARE #CategoryId INT;
DECLARE curs CURSOR FOR
SELECT Name, Manufacturer, Source, SourceDetailUrl, MainPrice, SalesPrice, [Description], ImageUrl, GroupId, ParentCategoryId, CategoryId
FROM INSERTED
OPEN curs
FETCH NEXT FROM curs INTO #Name, #Manufacturer, #SourceDetailUrl, #MainPrice, #SalesPrice, #Description, #ImageUrl, #GroupId, #ParentCategoryId, #CategoryId
WHILE ##FETCH_STATUS = 0
BEGIN
IF EXISTS (SELECT * FROM Products WHERE Name = #Name AND Manufacturer = #Manufacturer AND Source = #Source AND SourceDetailUrl = #SourceDetailUrl)
BEGIN
UPDATE Products SET MainPrice = #MainPrice, SalesPrice = #SalesPrice WHERE Name = #Name AND Manufacturer = #Manufacturer AND Source = #Source AND SourceDetailUrl = #SourceDetailUrl
END
ELSE
BEGIN
INSERT INTO Products (Name, Manufacturer, MainPrice, SalesPrice, [Description], Source, SourceDetailUrl, ImageUrl, GroupId, ParentCategoryId, CategoryId)
VALUES (#Name, #Manufacturer, #MainPrice, #SalesPrice, #Description, #Source, #SourceDetailUrl, #ImageUrl, #GroupId, #ParentCategoryId, #CategoryId)
END
DELETE FROM ProductsTemp WHERE Name = #Name AND Manufacturer = #Manufacturer AND Source = #Source AND SourceDetailUrl = #SourceDetailUrl
FETCH NEXT FROM curs INTO #Name, #Manufacturer, #SourceDetailUrl, #MainPrice, #SalesPrice, #Description, #ImageUrl, #GroupId, #ParentCategoryId, #CategoryId
END
CLOSE curs
DEALLOCATE curs
END

Retrieve all rows from all database tables with "Where" condition

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.

Pass Column Name as parameter

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

Passing value to one table and updating in parent table

I have two tables.
dbo.Emp
EmpID(PK) | Name | TypeID(FK)
dbo.EmpType
TypeID(PK) | Type
TypeID: AutoIncrement only in dbo.EmpType
When I update value for TypeID in Emptype, it needs get stored in TypeID of dbo.Emp
I used SP which is not working.
Create Procedure bridge_Type(
#EmpID INT,
#Name varchar(50),
#Mob2 numeric(10,0),
#Email varchar(50),
#Type varchar(50)
)
AS
DECLARE #TYPEID int
Set NOCOUNT OFF
BEGIN TRANSACTION
Insert into dbo.Emp VALUES (#EmpID, #Name, #Mob2, #Email, #TYPEID)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
INSERT INTO dbo.EmpType VALUES (#Type)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
declare #id int
SET #id= #TYPEID;
Update Dbo.Emp
Set #TYPEID= (Select TypeID from dbo.EmpType
WHERE TypeID=#typeID)
COMMIT
Try This SP, This will first insert the EmpType, and From SCOPE_IDENTITY() it will get the Inserted Identity Value, and then insert emp.
Create Procedure bridge_Type(
#EmpID INT,
#Name varchar(50),
#Mob2 numeric(10,0),
#Email varchar(50),
#Type varchar(50)
)
AS
DECLARE #TYPEID int
Set NOCOUNT OFF
BEGIN TRANSACTION
INSERT INTO dbo.EmpType VALUES (#Type)
SET #TYPEID = SCOPE_IDENTITY()
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
Insert into dbo.Emp VALUES (#EmpID, #Name, #Mob2, #Email, #TYPEID)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
COMMIT
Not 100% sure why you would be updating the typeID in your EmpType table (particularly as it is an autoincrement key), however, you could look at updating your FK constraint to 'cascade on update':
When to use "ON UPDATE CASCADE"
http://msdn.microsoft.com/en-us/library/aa933119(v=sql.80).aspx

Categories