Stored procedure in MS SQL Server 2005 - sql-server-2005

Here I got a scenario: When I press a button in client application (developed in Delphi) a stored procedure is activated. The stored procedure first declares a cursor for a select statement which returns two columns-BankID and BankCategoryID.Then I need to fetch each row inside the cursor into a record and check for the BankCategoryID and return a resultset according to the BankCategoryID like:
CASE WHEN fetched_record.BankCategoryID=1 THEN
SELECT STATEMENT1 WHEN fetched_record.BankCategoryID=2 THEN
SELECT STATEMENT2 and so on...
and then I return the result set retrieved from any of the above cases to my client application. Is thi possible?

Perhaps you'd want to use an IF as a control statement within your cursor?
WHILE ##FETCH_STATUS = 0
BEGIN
IF #BankCategoryID=1
BEGIN
SELECT Baz From Bat;
DECLARE #Spam bit;
SELECT #Spam = 0;
END
IF #BankCategoryID=2
BEGIN
SELECT Foo FROM Bar;
END
FETCH NEXT FROM MyCursor INTO #BankID, #BankCategory
END
Here's a sample TSQL cursor. You'd be loading your two column values into 2 variables: #BankID and #BankCategoryID. i.e. FETCH NEXT FROM MyCursor INTO #BankID, #BankCategoryID
Aside: I'm wondering if this could be done all without a cursor? In either case, the above should work for you in implementing more TSQL statements in each iteration of your cursor.

Related

Db2 Stored Procedure results nothing

I am new to DB2 Development. I am trying to write a procedure that reads records from a file. Everything is going fine, but my procedure is not showing any results.
This is my code, I request you to please go through this & kindly correct me if I am wrong.
CREATE OR REPLACE PROCEDURE REA_DT ()
LANGUAGE SQL
DYNAMIC RESULT SETS 1
P1: BEGIN
DECLARE TB_NAME VARCHAR(128);
DECLARE EOF INT DEFAULT 0;
DECLARE STMT VARCHAR(500);
-- Declare cursor
DECLARE cursor1 CURSOR WITH RETURN for
SELECT * FROM MT;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET EOF=1;
-- Cursor left open for client application
OPEN cursor1;
WHILE EOF=0
DO
FETCH FROM cursor1 INTO TB_NAME;
END WHILE;
CLOSE cursor1;
END P1
I don't know what to place after FETCH to display the variable value.
Thanks In advance
Now i can view all the records from my table. could you please let me know why this got happened. This is not my desired result. I am expecting to read records from the table on by one.
You have declared the cursor using WITH RETURN, indicating that you want the stored procedure to return a result set back to the application that calls the procedure.
But instead of simply issuing the OPEN CURSOR statement, you proceed to use the WHILE loop to read all rows from the cursor and then close the cursor. Thus there is nothing returned to the application that called the stored procedure.
To return a cursor so the calling application can process the results from it, simply issue the OPEN CURSOR statement before the end of the procedure. Do not FETCH FROM or CLOSE the cursor.

How to run a query multiple times with different parameters?

I'm trying to figure out the best way to get a query to run multiple times with different parameters. I've tried putting it as a stored procedure and running it with cursors, but I'm pretty novice at the cursor concept. Here is the query and my first attempt with cursor.
SELECT
AVG([processingseconds])
FROM [nucor_historical_data].[dbo].[test_Lift_Matrix]
Where ActualGauge between 0 and .21875 and ActualWidth between 0 and 55
and inches between 0 and 120 and MaxLiftWeight between 0 and 10000 and
processingseconds is not null
So the parameters I need to loop through are in the where statement. I have combinations for all these groupings you see in another table.
someone suggested trying this to me earlier from another stack question, so I tested with one parameter but couldn't get it working. Is there a better way to attempt this?
DECLARE #param varchar(200)
-- getting your parameter from the table
DECLARE curs CURSOR LOCAL FAST_FORWARD FOR
SELECT gauge FROM groupings
OPEN curs
FETCH NEXT FROM curs INTO #param
-- executing your stored procedure once for every value of your parameter
WHILE ##FETCH_STATUS = 0 BEGIN
EXEC group_average #param
FETCH NEXT FROM curs INTO #param
END
CLOSE curs
DEALLOCATE curs
A stored procedure is the way to go here - passing the parameters as arguments.
Here is a watered down example of what you are trying to do, that is, run the select statement repeatedly using the values from another table as the inputs. You'll need to adapt to your specifics, I only did a subset of your fields:
DECLARE #UniqueId int
DECLARE #AgMin numeric(10,4)
DECLARE #AgMax numeric(10,4)
DECLARE #tmp TABLE (UniqueId INT, AgMin numeric(10,4), AgMax numeric(10,4))
INSERT #tmp SELECT ID, AGMIN, AGMAX FROM [YOUROTHERTABLEWITHTHESENUMBERS]
SELECT TOP 1 #UniueId=UniqueId, #AGMin=AGMin, #AGMAX=AgMax FROM #tmp
WHILE (##rowcount > 0)
BEGIN
SELECT AVG([processingseconds]) FROM test_Lift_Matrix Where ActualGauge between #AGMIN and #AGMAX (the rest of your conditions...)
DELETE FROM #tmp WHERE UniqueId=#UniqueId
SELECT TOP 1 #UniqueId=UniqueId, #AGMin=AGMin, #AGMAX=AgMax FROM #tmp
END
I think what you're trying to do is a execute a dynamic query (because of the changing where clause) having it behaviour like a static query.
I suppose your query is executed upon criteria coming from client application.
If this is the case try to a parametrized dinamic query string executed through sp_executesql.
This is a very effective technique. See more following:
http://www.sommarskog.se/dyn-search-2005.html

Stored Procedure Loop

I have a stored procedure which generates some xml based on 3 parameters: #property_id, #property_component_id and #return_as_xml. The value for #return_as_xml will be the same for all records which is 0.
I have modified this and now need to run it for multiple Property records based on a specific condition i.e. for active and leased properties. A one-many relationship exists between property and property_component, so a property can have multiple property_components and does have at least one corresponding record.
I some how need to do a select of the records I want based on the active and leased fields in the Property table. Select the corresponding property_component_id from the property_component table where a corresponding property_id exists. I then want to loop through each of the result rows, execute the stored procedure passing in new parameters for each row.
I don't want to modify the stored procedure more than I already have as it is executed from an asp.net console application which requires it to return xml for a single property, ie I don't want alter the stored procedure to return xml for multiple properties.
My stored procedure execution is just the standard generated sql server code:
DECLARE #return_value int
EXEC #return_value = [dbo].[p_CPGUploader__FetchXMLForProperty_RCA]
#property_id = 106016,
#property_component_id = 108382,
#return_as_xml = 0
SELECT 'Return Value' = #return_value
GO
How can I modify this to work for my described scenario, how can I get select a recordset then loop through it executing the stored procedure passing based on values from each row of the select? I come from an asp.net background and my SQL Server skills are extremely limited so any assistance would be greatly appreciated. I am using SQL Server 2008 R2 although I believe the original stored procedure was written in 2004 if that's of any relevance.
If you really can't change the stored procedure, then you can create a loop using a cursor.
I wouldn't advise this course of action unless absolutely necessary though.
declare c cursor local read_only for
select property_component_id from propertiestable
declare #id
open c
fetch from c into #id
while ##fetch_status=0
begin
EXEC #return_value = [dbo].[p_CPGUploader__FetchXMLForProperty_RCA]
#property_id = 106016,
#property_component_id = #id,
#return_as_xml = 0
fetch next from c into #id
end
close c
deallocate c

Best way to replace cursor in SQL Server 2008

I want to replace the cursor code from my stored procedure
DECLARE CursorXD CURSOR FOR
SELECT
IDOrdre, Quantity,fabnum
FROM prod_ordreplanificationdetail
WHERE fab = #num
AND ordre = #ord
OPEN CursorXD
FETCH NEXT FROM CursorXD INTO #correctionnumsap, #correctionquantite, #correctionnumfabrication
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC INSERT#prod #idordre = #correctionnumsap,
#quantite = #correctionquantiteneg,
#fabnum = #correctionnumfabrication
FETCH NEXT FROM CursorXD INTO #correctionnumsap, #correctionquantite, #correctionnumfabrication
END
CLOSE CursorXD
DEALLOCATE CursorXD
What is the best way to replace this cursor to increase the performance??
Any suggestion?
Here's a option, but I made a couple of assumptions
INSERT INTO prod
SELECT IDOrdre, Quantity,fabnum
FROM prod_ordreplanificationdetail
WHERE fab=#num
AND ordre=#ord
Assumptions:
SP INSERT#prod only does an INSERT and no other data manipulation
SP INSERT#prod inserts into a table called prod and there are only three columns in the table
You can use WHILE loop instead of CURSOR by maintaining the nth row value. It is too good performance wise compare to CURSOR. If you tell clearly what you need, so we can walk into same road.

In T-SQL / SQL Server 2000, referencing a particular row of a result set

I want to reference the nth row of the #temptable (at the second SQL comment is below). What expression will allow me to do so?
DECLARE #counter INT
SET #counter = 0
WHILE (#counter<count(#temptable))
--#temptable has one column and 0 or more rows
BEGIN
DECLARE #variab INT
EXEC #variab = get_next_ticket 3906, 'n', 1
INSERT INTO Student_Course_List
SELECT #student_id,
-- nth result set row in #temptable, where n is #count+1
#variab
SET #counter = #counter +1
END
Cursor (will this work?):
for record in (select id from #temptable) loop
--For statements, use record.id
end loop;
Normally in a relational database like SQL Server, you prefer to do set operations. So it would be best to simply have INSERT INTO tbl SOMECOMPLEXQUERY even with very complex queries. This is far preferable to row processing. In a complex system, using a cursor should be relatively rare.
In your case, it would appear that the get_next_ticket procedure performs some significant logic which is not able to be done in a set-oriented fashion. If you cannot perform it's function in an alternative set-oriented way, then you would use a CURSOR.
You would declare a CURSOR on your set SELECT whatever FROM #temptable, OPEN it, FETCH from the cursor into variables for each column and then use them in the insert.
Instead of using a while loop (with a counter like you are doing) to iterate the table you should use a cursor
Syntax would be:
DECLARE #id int
DECLARE c cursor for select id from #temptable
begin
open c
fetch next from c into #id
WHILE (##FETCH_STATUS = 0)
BEGIN
--Do stuff here
fetch next from c into #id
END
close c
deallocate c
end