passing parameters to a stored procedure from a temp table - sql-server-2008

I have a senario where i have to pass parameters to a stored procedure from a temptable
#student(table)
StudentID Class
10008 A
10009 A
10010 C
The sproc accepts 2 parameters StudentID and Class.
Student_Fail #StudentID,#Class
I would like to execute this stored procedure for all the studentID(3 times).
How can this be done? using while loop?

Well ideally you should re-write the stored procedure so that it can just use the #temp table directly, or create a different stored procedure, or just replicate in this code what the stored procedure tries to do for a single row. (Set-based operations are almost always better than processing one row at a time.)
Short of that, you'd have to use a cursor or while loop (and no they aren't really different).
DECLARE #StudentID INT, #Class CHAR(1);
DECLARE c CURSOR LOCAL FAST_FORWARD
FOR SELECT StudentID, Class FROM #student;
OPEN c;
FETCH c INTO #StudentID, #Class;
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC dbo.Student_Fail #StudentID, Class;
FETCH c INTO #StudentID, #Class;
END
CLOSE c;
DEALLOCATE c;

As you've indicated, a while loop will do:
declare #StudentID int
declare #Class char(1)
while exists (select 1 from #student)
begin
select top 1 #StudentID = StudentID
, #Class = Class
from #student
exec Student_Fail #StudentID, #Class
delete from #student where #StudentID = StudentID
end

Yes, this could be implemented as a WHILE loop, or as a CURSOR, since in this case they will do essentially the same thing, a row-by-row operation.
However, the ideal solution would be to re-implement the Student_Fail fail stored procedure to make it set-based instead of procedural.
For example, you can change your stored procedure to accept a table-valued parameter.
First, create the table type:
CREATE TYPE dbo.StudentClassTableType AS TABLE
( StudentID int, Class varchar(50) )
Next, alter the stored procedure (or create a new stored procedure) to accept the table type:
CREATE PROCEDURE dbo.usp_FailStudents
(#tvpStudentsToFail dbo.StudentClassTableType READONLY)
-- Perform set-based logic using your table parameter.
UPDATE sc
SET Fail = 1
FROM dbo.StudentClass sc
JOIN #tvpStudentsToFail fail
ON fail.StudentID = sc.StudentID
AND fail.Class = sc.Class

Related

MySQL Stored procedure returning all results ignoring WHERE claus

I have two stored procs which i call from my laravel application.
My laravel application passes in a cID parameter which is then passed to the stored procedure as the "where clause". But it seems something is going astray and possibly my variables arent set up properly.
Also i know that laravel IS passing the correct cID to my stored proc because i enabled the logs for mysql to see if it was passing any params.
Also the stored procedure select statement runs fine as a query if i manually set the ClientID = '';
My stored proc sends ALL clients and cards to the view, totally ignoring the where clause.
Laravel code:
Route::get('/clients/{cID}', function ($cID) {
$details = DB::select('CALL sp_Details(' . DB::raw($cID) . ')');
$cards = DB::select('CALL sp_Cards(' . DB::raw($cID) . ')');
return view('client.show', compact('details','cards'));
});
Any my Stored Proc
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_Details`(IN cID int )
BEGIN
SET #ClientID = cID;
SELECT
ClientID,
Client_Name
FROM accounts
where #ClientID = cID;
END
Stored Proc #2
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_Cards`(cID int)
BEGIN
SET #ClientID = cID;
SELECT
ClientID,
Code
FROM cards
where cID = #ClientID;
END
You are using local variables like #ClientID and you are confusing it to column names, must change your code to avoid them and there is no necessary use the local variable:
CREATE PROCEDURE `sp_Details`(IN cID int )
BEGIN
SELECT
ClientID,
Client_Name
FROM accounts
where ClientID = cID;
END
The other proc:
CREATE PROCEDURE `sp_Cards`(cID int)
BEGIN
SELECT
ClientID,
Code
FROM cards
where ClientID = cID;
END

MySql syntax error on procedure parameter

I am trying to write a simple procedure but am encountering a syntax error at the first parameter. As best I can tell I'm following the syntax of CREATE PROCEDURE correctly.
I am limited to accessing my database with phpMyAdmin. Here is the create script I'm trying to run:
DROP PROCEDURE IF EXISTS product_index_swap/
CREATE PROCEDURE product_index_swap (#id INT, #oldIndex INT, #newIndex INT)
BEGIN
DECLARE #swapID;
SET #swapID = (SELECT `id` FROM `product` WHERE `order_index` = #newIndex LIMIT 1);
UPDATE `products` SET `order_index` = (CASE WHEN `id` = #id THEN #newIndex
WHEN `id` = #swapID THEN #oldIndex END)
WHERE `id` IN (#id, #swapID);
END
I am using the option on phpMyAdmin to change the delimiter to /.
I receive a syntax error "near '#id INT, #oldIndex INT....". I thought I may encounter more delimiter errors since I'm not entirely clear on the scope of them. I believe if that was the problem the error would be on a new line in the procedure when it failed to understand a semicolon, not at the parameters declaration.
You're using the Microsoft SQL Server convention of putting # before all the parameters and local variables. MySQL doesn't do this.
In MySQL syntax, procedure parameters have no sigil.
Also parameters are typically declared IN or OUT or INOUT.
CREATE PROCEDURE product_index_swap (IN id INT, IN oldIndex INT, IN newIndex INT)
BEGIN
DECLARE swapID;
...
MySQL variables that have the # sigil are session variables.
See also:
https://dev.mysql.com/doc/refman/5.7/en/create-procedure.html
https://dev.mysql.com/doc/refman/5.7/en/declare-local-variable.html
https://dev.mysql.com/doc/refman/5.7/en/set-variable.html
In MySQL, the #var variables are session level variables.
Use normal variables without the # and make sure you do not have conflict with column names:
CREATE PROCEDURE product_index_swap (in_id INT, in_oldIndex INT, in_newIndex INT)
BEGIN
DECLARE v_swapID int;
SELECT id into v_swapID
FROM product
WHERE order_index = in_newIndex
LIMIT 1;
UPDATE products
SET order_index = CASE WHEN id = in_id THEN in_newIndex
WHEN id = v_swapID THEN in_oldIndex
END
WHERE id IN (in_id, v_swapID);
END

Call MS SQL Server Stored Procedure with multiple parameters inclusive of table-value parameter

After doing some research here and online I am at a loss as to whether this is possible. What I want to do is call a stored procedure that has several parameters one of which is a table-value parameter.
This is my stored procedure snippet:
ALTER PROCEDURE [dbo].[procName]
#Action nvarchar(10) = 'view'
,#var1 int = 0
,#var2 int = 0
,#var3 myType ReadOnly
I now have another procedure (proc2) that has the following lines:
insert into #varX
select top 5
field1, field2
from
sourceTable
print 'Processing from table values...'
exec dbo.procName 'refresh', -1, 0, #varX
Note that varX and var3 are of the same type MyType
When I execute proc2 I get the error that I am specifying too many arguments for dbo.procName
I am at the point in thinking it is not possible to specify multiple parameters inclusive of a table-value parameter to a stored procedure. I am now tending towards the thought of changing my procName definition to only have one parameter (as all of the examples online seem to have) and have my table-value paramter act as an array of parameter values inclusive of the information I had in my previous select statement (in proc2). If however it is possible to do this call, please illustrate how this is done.
Thanks
This compiles and runs for me:
create type TT as table (ID int not null);
go
create procedure P1
#Val1 int,
#Val2 TT readonly,
#Val3 int
as
select #Val1 as Val1,ID,#Val3
from #Val2;
go
create procedure P2
as
declare #T TT;
insert into #T(ID) values (1),(2)
exec P1 10,#T,13
go
exec P2
Result:
Val1 ID
----------- ----------- -----------
10 1 13
10 2 13
So, I don't know what your issue is, but it's not being able to mix table and non-table parameters.

No-Data error in stored procedure

I am in the process of converting a SQL Server 2005 database to MySQL and having problems with a Stored procedure. I'm new to MySQL stored procedures so I'm sure it is a problem with my conversion but I'm not seeing it.
The stored procedure is supposed to generate a temporary table which is used to populate a Data Grid View in a vb.net application. However, I'm getting the error "Data No Data - Zero rows fetched, selected or processed.". Seems simple enough but the select procedure in the stored procedure will get data if I just run it as a query which is why I don't understand why the error.
I'm really hoping someone can tell me why because I have several hundred stored procedures to convert and I'm having this problem on the very first one.
Here's the Stored Procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS `usp_get_unassigned_media`$$
CREATE DEFINER=`showxx`#`67.111.11.110` PROCEDURE `usp_get_unassigned_media`()
BEGIN
/* GET CURSOR WITH LOCAL LOCATIONS */
DECLARE intKey INT;
DECLARE dteDateInserted DATETIME;
DECLARE vchIdField VARCHAR(200);
DECLARE vchValueField VARCHAR(200);
DECLARE intLastKey INT;
/*TAKE OUT SPECIFIC PLAYLIST ITEMS IF TOO SLOW*/
DECLARE csrMediaToBeAssigned CURSOR FOR
SELECT
`media`.`key` AS `key`,
`media`.`date_inserted` AS `date_inserted`,
`media_detail_types`.`id` AS `id`,
`media_details`.`value` AS `value`
FROM (`media`
LEFT JOIN (`media_detail_types`
JOIN `media_details`
ON ((`media_detail_types`.`key` = `media_details`.`detail_key`)))
ON ((`media_details`.`media_key` = `media`.`key`)))
WHERE ((`media`.`is_assigned` = 0)
AND ((`media_detail_types`.`id` = 'Volume Name')
OR (`media_detail_types`.`id` = 'Drive Id')))
ORDER BY `media`.`key`,`media`.`date_inserted`,`media_detail_types`.`id`;
OPEN csrMediaToBeAssigned;
DROP TEMPORARY TABLE IF EXISTS temp_unassigned_media;
CREATE TEMPORARY TABLE temp_unnassigned_media
(temp_key INT, DateInserted DATETIME, IdField VARCHAR(200), ValueField VARCHAR (200))
ENGINE=MEMORY;
SET intLastKey = 0;
/*--GET FIRST RECORD */
FETCH FROM csrMediaToBeAssigned
INTO intKey, dteDateInserted, vchIdField, vchValueField;
/*--LOOP THROUGH CURSOR */
WHILE intLastKey = 0 DO
/*--DATA SHOULD BE IN DRIVE ID THEN VOLUME NAME */
INSERT INTO temp_unnassigned_media
VALUES (intKey, dteDateInserted, vchValueField, '');
FETCH NEXT FROM csrMediaToBeAssigned
INTO intKey, dteDateInserted, vchIdField, vchValueField;
UPDATE temp_unnassigned_media
SET IdField = vchValueField
WHERE temp_key = temp_key;
FETCH NEXT FROM csrMediaToBeAssigned
INTO intKey, dteDateInserted, vchIdField, vchValueField;
END WHILE;
SELECT *
FROM temp_unnassigned_media
ORDER BY date_inserted;
CLOSE csrMediaToBeAssigned;
/*DEALLOCATE csrMediaToBeAssigned */
/*DROP TABLE #temp_unnassigned_media */
END$$
DELIMITER ;
You never hit a condition where that WHILE loop will exit; you initialize intLastKey variable, but it never changes, so you fetch through the entire resultset. The exception is thrown when you fetch again, after the last record.
The normative pattern is to declare a CONTINUE HANDLER, which MySQL will execute when the NOT FOUND condition is triggered. The handler is normally used to set a variable, which you can then test, so you know when to exit the loop.
In your case, it looks like just adding this line, after your DECLARE CURSOR statement and before the OPEN statement, would be sufficient:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET intLastKey = 1;

Calling a stored procedure within an IF statement MySQL

Does anybody know if this is allowed?
IF CALL GET_RIGHT_NODE(edge) = 15
THEN
SELECT "IT WORKS";
I'm getting an error on this syntax, is it possible any other way?
The return values from stored procedures should be captured in OUT paramters (whereas those from user defined functions can be captured as #returnValue = function()).
So, your GET_RIGHT_NODE should take an OUT parameter and set it to the return value.
CREATE PROCEDURE GET_RIGHT_NODE
(
#edge INT,
#returnValue INT OUTPUT
)
AS
-- Definition of the proc.
then you would call the procedure as follows:
DECLARE #returnValue INT
CALL GET_RIGHT_NODE(#edge, #returnValue)
IF (#returnValue = 15)
THEN
SELECT 'IT WORKS'