How to execute a procedure having cursor in SQL Server 2008? - sql-server-2008

I know how to execute a stored procedure in SQL Server2008 but I'm clueless in executing a stored procedure containing a cursor in it.
My code:
BEGIN TRANSACTION
GO
DROP PROCEDURE SampleProcedure
GO
CREATE PROCEDURE SampleProcedure
AS
DECLARE #FirstName varchar(64)
DECLARE c1 CURSOR READ_ONLY
FOR
SELECT FIRST_NAME
FROM EMPLOYEE
OPEN c1
FETCH NEXT FROM c1 INTO #FirstName
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #FirstName
FETCH NEXT FROM c1 INTO #FirstName
END
CLOSE c1
DEALLOCATE c1
COMMIT TRANSACTION
I have seen executing a procedure with cursor in Oracle but couldn't find in SQL Server. Please tell me how to execute the stored procedure which contains cursor.
---Thanks

Executing the SP.
EXEC SampleProcedure

Related

MySQL8 Procedure - Use Parameters in Cursor

I'm trying to use input parameters of a stored procedure within a cursor of the procedure.
Calling the procedure as follows results in an Error
-- -role- -table- -cond-
CALL grantRoleToUsersFromWhere('Student', 'studenten', true);
Error Code: 1146. Table 'uni4.utable' doesn't exist
This tells me that the parameter 'userTable' was not written to the variable 'uTable' OR 'uTable' is not recognized as a variable at all by the cursor Statement.
I tried different approaches storing / using the parameters. e.g. use them directly or store them in a Variable with a SET statement. However, if I try to use SET uTable=userTable; before the cursor declaration, MySQL WorkBench won't accept the Procedure declaration.
I spent quite some time on this but I think I'm missing an important yet simple part :-)
DROP PROCEDURE IF EXISTS grantRoleToUsersFromWhere;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE grantRoleToUsersFromWhere(IN grantRole VARCHAR(30), IN userTable VARCHAR(30), IN addCondition VARCHAR(50))
BEGIN
DECLARE workUser VARCHAR(30) default '';
DECLARE gRole VARCHAR(30) default grantRole;
DECLARE uTable VARCHAR(30) default userTable;
DECLARE aCond VARCHAR(50) default addCondition;
DECLARE cur1 CURSOR FOR SELECT Name FROM uTable WHERE aCond;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO workUser;
GRANT gRole TO workUser;
END LOOP;
CLOSE cur1;
END $$
DELIMITER ;
Create dynamic cursors directly is not possible. You can however use VIEW's to achieve the same thing. See sample.
CREATE PROCEDURE p1 (select_statement VARCHAR(255))
BEGIN
DECLARE v1,v2 VARCHAR(255);
DECLARE c CURSOR FOR SELECT * FROM t;
SET #v = CONCAT('create temporary table t as ',select_statement);
PREPARE stmt1 FROM #v;
EXECUTE stmt1;
OPEN c;
FETCH c INTO v1,v2;
SELECT v1,v2;
END//
' DECLARE cur1 CURSOR FOR SELECT Name FROM uTable WHERE aCond;' is not possible mysql does not do variable substitution (for table name). Your read loop is infinite because you don't declare a continuation handler and test for not found in the read loop.

Displaying the records from a mysql stored procedure

I am just starting to learn how to write stored procedures in MYSQL and I've hit a roadblock.
I wrote the following code:
DELIMITER $$
DROP PROCEDURE IF EXISTS `emscribedx`.`countcodes` $$
CREATE PROCEDURE `emscribedx`.`countcodes` ()
BEGIN
declare doneprocessing int default 0;
declare thisaccount varchar(50);
declare countcursor cursor for select acct from patientid where patienttype='P';
declare continue handler for not found
set doneprocessing = 1;
Fetch countcursor into thisaccount;
Repeat
select * from doc_table where acct = thisaccount;
until doneprocessing = 1
END repeat;
close countcursor;
END $$
DELIMITER ;
I would like to display the results of the select statement that occurs after the repeat statement. But how do I do that? When I execute the stored procedure, nothing happens?
Thank you,
Elliott
The procedure can only return the results of a single query, why not use this instead?
SELECT doc_table.*
FROM doc_table
INNER JOIN patientid
ON patientid.acct = doc_tableacct
WHERE patientid.patienttype='P';
It can be put inside of a procedure if you want.

call aspnet_Delete_User SP in trigger

I have a trigger in students table that deletes related records from other tables when i delete a student. I want to delete student's membership data by calling aspnet_delete_user stored procedure in the trigger . but this works just if I delete one student . and if I remover multiple students in one query it doesn't work .
How to call this SP for multi-row operation trigger ?
You'd have to use a cursor or build a dynamic SQL string (which uses a cursor without saying so). Alternatively, you could copy the logic from the stored procedure and see if you can tailor it to become set-based - I haven't looked at the procedure, so I'm not sure if this is feasible, practical or even possible, but it's the first thing I try to do before adding cursors or dynamic SQL to a trigger.
For a cursor, something like this (I'm guessing you pass a GUID or something to the procedure, but I have no idea):
CREATE TRIGGER dbo.StudentAfterDelete
ON dbo.Students
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #MemberID UNIQUEIDENTIFIER;
DECLARE c CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR SELECT MemberID FROM deleted;
OPEN c;
FETCH NEXT FROM c INTO #MemberID;
WHILE ##FETCH_STATUS <> -1
BEGIN
EXEC dbo.aspnet_delete_user #MemberID;
FETCH NEXT FROM c INTO #MemberID;
END
CLOSE c;
DEALLOCATE c;
END
GO
Dynamic SQL, same assumptions:
CREATE TRIGGER dbo.StudentAfterDelete
ON dbo.Students
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql += 'EXEC dbo.aspnet_delete_user '''
+ CONVERT(VARCHAR(36), MemberID) + ''';' FROM deleted;
EXEC sp_executesql #sql;
END
GO
However including the missing information up front is more useful. Don't assume that everyone who works with SQL Server has any clue what aspnet_delete_user does.
Maybe something like this:
CREATE TRIGGER TheNameOfTheTrigger
ON YourTableYouWantToTriggerOn
AFTER DELETE
AS
DECLARE #yourPrimaryKey int
DECLARE delete_cursor CURSOR FOR
SELECT
yourPrimaryKey
FROM
deleted
OPEN delete_cursor
FETCH NEXT FROM delete_cursor
INTO #yourPrimaryKey
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC aspnet_delete_user #yourPrimaryKey
FETCH NEXT FROM delete_cursor INTO #yourPrimaryKey
END
CLOSE delete_cursor
DEALLOCATE delete_cursor
GO
See more information here and here

Stored Procedures calls two other stored procedures, but only 1 seems to run. No error thrown

Problem:
Hi I've got two stored procedures, that I try to run from another one.
- If I call them one after the other from phpmysqladmin, everything works fine.
- If I call the stored procedure, that calls the other two, I don't get an error. So far so good. But the problem is, that the operations from the second stored procedure aren't executed.
Already tried to run it in just one sp...
I also tried to run both stored procedures (sp1,sp2) in one stored procedure, with the same effect.
Could that be the problem?
In the first sp I use a statement like this:
Select #var:= ....
Here is the code:
In the first stored procedure I generate a dynamic query and execute it.
Procedure 1
CREATE PROCEDURE `sp_prepare_valid_choices`(IN p_request_id Bigint)
BEGIN
DECLARE num_rows INT DEFAULT 0;
DECLARE no_more_rows BINARY;
DECLARE no_more_subrows BINARY;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE var_choice_group BIGINT DEFAULT 0;
-- Declare Cursor for the loop through the constraint_groups
DECLARE cur_constraint_group CURSOR FOR
SELECT distinct choice_constraint_group FROM casainte_choice_constraint
WHERE choice_id_rule_parameter IN (SELECT choice_id FROM casainte_request_detail
where request_id = p_request_id);
-- DECLARE 'handlers' for exceptions
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET no_more_rows := TRUE;
-- DELETE OLD VALUES
DELETE FROM tmp_casainte_valid_choices
WHERE request_id = p_request_id;
DELETE FROM tmp_casainte_valid_choices_for_request
WHERE request_id = p_request_id;
-- OPEN CURSOR AN PROCESS CONSTRAINT_GROUPS
OPEN cur_constraint_group;
SELECT FOUND_ROWS() INTO num_rows;
choice_group_loop: LOOP
FETCH cur_constraint_group
INTO var_choice_group;
IF no_more_rows THEN
CLOSE cur_constraint_group;
LEAVE choice_group_loop;
END IF;
-- PAYLOAD
-- INSERT THE VALID CHOCIES INTO tmp_casainte_valid_choices
SELECT #var_sql_query := CONCAT('INSERT INTO tmp_casainte_valid_choices ','SELECT ',p_request_id,' as request_id, `casainte_choice_constraint`.`choice_constraint_id`,`casainte_choice_constraint`.`choice_constraint_group`
,AVG(IF (`casainte_request_detail`.`choice_varchar_value`', `casainte_choice_constraint`.`choice_constraint_operator`, '\'',`casainte_choice_constraint`.`choice_constraint_value`, '\'',',1,0 )) AS VALID
FROM `casainte_choice_constraint`
LEFT JOIN `casainte_request_detail` ON `casainte_request_detail`.`choice_id` = `casainte_choice_constraint`.`choice_id_rule_parameter`
WHERE `casainte_choice_constraint`.choice_constraint_group =' , var_choice_group,
' GROUP BY `casainte_choice_constraint`.choice_constraint_group')
FROM `casainte_choice_constraint` WHERE `casainte_choice_constraint`.choice_constraint_group = var_choice_group;
PREPARE SQL_STATEMENT FROM #var_sql_query;
EXECUTE SQL_STATEMENT;
-- INCREMENT THE COUNTER
SET loop_cntr = loop_cntr + 1;
END LOOP choice_group_loop;
END$$
Procedure 2
In the second stored procedure I insert the values into a table.
delimiter $$
CREATE PROCEDURE `sp_insert_valid_choices`(IN p_request_id Bigint)
BEGIN
INSERT INTO tmp_casainte_valid_choices_for_request
(request_id, choice_id)
SELECT DISTINCT p_request_id, choice_id FROM casainte_choice ac
-- RULE 1 ALL CHOICES WITHOUT CONSTRAINTS
WHERE ac.choice_id NOT IN (SELECT choice_id_rule_target FROM casainte_choice_constraint)
-- RULE 2 ALL CHOICES WITH CONSTRAINTS, THAT ARE NOT YET ANSWERED
OR ac.choice_id NOT IN (SELECT choice_id_rule_target FROM casainte_choice_constraint
WHERE choice_id_rule_parameter IN (SELECT choice_id FROM casainte_request_detail WHERE request_id = p_request_id))
-- RULE 3 ALL CHOICES WITH CONSTRAINTS, THAT ARE TRUE
OR ac.choice_id IN (SELECT choice_id_rule_target FROM casainte_choice_constraint
WHERE choice_constraint_group IN (SELECT choice_constraint_group FROM tmp_casainte_valid_choices WHERE request_id = p_request_id AND VALID = 1));
END$$
Procedure 3
The third stored procedure calls the 1st sp, then the 2nd sp.
delimiter $$
CREATE PROCEDURE `sp_generate_valid_choices`(IN p_request_id Bigint)
BEGIN
Call `sp_prepare_valid_choices`(p_request_id);
Call `sp_insert_valid_choices`(p_request_id);
END$$
You don't have "delimiter $$" at the top of Procedure 1. Could this be causing the problem?

Convert SQL Server stored procedure to MySQL

I need to convert the following stored procedure of SQL Server to MySQL. I am new to MySQL.
CREATE PROC InsertGenerator
(#tableName varchar(100)) as
--Declare a cursor to retrieve column specific information
--for the specified table
DECLARE cursCol CURSOR FAST_FORWARD FOR
SELECT column_name,data_type FROM information_schema.columns
WHERE table_name = #tableName
OPEN cursCol
DECLARE #string nvarchar(3000)
--for storing the first half
--of INSERT statement
DECLARE #stringData nvarchar(3000)
--for storing the data
--(VALUES) related statement
DECLARE #dataType nvarchar(1000) --data types returned
--for respective columns
SET #string='INSERT '+#tableName+'('
SET #stringData=''
DECLARE #colName nvarchar(50)
FETCH NEXT FROM cursCol INTO #colName,#dataType
IF ##fetch_status<>0
begin
print 'Table '+#tableName+' not found, processing skipped.'
close curscol
deallocate curscol
return
END
WHILE ##FETCH_STATUS=0
BEGIN
IF #dataType in ('varchar','char','nchar','nvarchar')
BEGIN
SET #stringData=#stringData+'''''''''+
isnull('+#colName+','''')+'''''',''+'
END
ELSE
if #dataType in ('text','ntext')
--if the datatype
--is text or something else
BEGIN
SET #stringData=#stringData+'''''''''+
isnull(cast('+#colName+' as varchar(2000)),'''')+'''''',''+'
END
ELSE
IF #dataType = 'money' --because money doesn't get converted
--from varchar implicitly
BEGIN
SET #stringData=#stringData+'''convert(money,''''''+
isnull(cast('+#colName+' as varchar(200)),''0.0000'')+''''''),''+'
END
ELSE
IF #dataType='datetime'
BEGIN
SET #stringData=#stringData+'''convert(datetime,''''''+
isnull(cast('+#colName+' as varchar(200)),''0'')+''''''),''+'
END
ELSE
IF #dataType='image'
BEGIN
SET #stringData=#stringData+'''''''''+
isnull(cast(convert(varbinary,'+#colName+')
as varchar(6)),''0'')+'''''',''+'
END
ELSE
--presuming the data type is int,bit,numeric,decimal
BEGIN
SET #stringData=#stringData+'''''''''+
isnull(cast('+#colName+' as varchar(200)),''0'')+'''''',''+'
END
SET #string=#string+#colName+','
FETCH NEXT FROM cursCol INTO #colName,#dataType
END
http://dev.mysql.com/doc/refman/5.0/en/stored-routines-syntax.html
This link contains the documentation on creating stored procedures and functions in MySql. You have quite a lot of code there so it may come down to 6 of 1 and half dozen of the other.
You can convert it to MySQL by using the following steps.
In SQL Server the parameters of the stored procedure are declared as
For Example:
CREATE PROCEDURE Strproc_example(
#strBillingPeriodID VarChar(200),
#result int OUT)
In MySQL it is
CREATE PROCEDURE Strproc_example(
v_strBillingPeriodID VarChar(200),
OUT v_result int )
In SQL server there is the As keyword. Remove that in MySQL
Then put a semicolon after in statement of SQL Server to convert it
into MySQL statements.