I am getting an error in MySQL procedure at EXEC () function:
What is the cause of error?
CREATE PROCEDURE get_string_try(in_strlen int, in_id int)
BEGIN
set #var:='';
while(in_strlen>0)
do
set #var:=concat(#var,IFNULL(ELT(1+FLOOR(RAND() * 53), 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'),'kovendan'));
set in_strlen:=in_strlen-1;
set #ix :=1;
while (#ix < 4)
do
set #select_column_insert:= ELT(#ix, 'address','lastname','middlename');
#SET #DynamicQuery_1 = ('UPDATE students set ' + #select_column_insert +' = '+ #var +' where id = '+in_id);
#SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = Database() AND TABLE_NAME = 'students' AND column_name = 'middlename' INTO #select_column_insert;
EXEC('UPDATE students set ' + #select_column_insert +' = '+ #var +' where id = '+in_id);
set #ix = #ix+1;
end while;
end while;
END $$
delimiter ;
CALL get_string_try(6,7);
And finally found the solution.
refer below:
DELIMITER $$
CREATE PROCEDURE get_string_try(in_strlen int, in_id int)
BEGIN
set #var:='';
while(in_strlen>0)
do
set #var:=concat(#var,IFNULL(ELT(1+FLOOR(RAND() * 53), 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'),'kovendan'));
set in_strlen:=in_strlen-1;
set #ix :=1;
while (#ix < 4)
do
set #select_column_insert:= ELT(#ix, 'address','lastname','middlename');
SET #DynamicQuery_1 = CONCAT('UPDATE students set ', #select_column_insert, '= ', "'", #var,"'" ,' where id = ',in_id);
PREPARE stmt FROM #DynamicQuery_1;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set #ix = #ix+1;
end while;
end while;
END $$
delimiter ;
CALL get_string_try(6,8);
I have a really simple query like:
BEGIN TRY
BEGIN TRAN;
DECLARE #CurrentPassword VARCHAR(255) = (SELECT TOP 1 [Password]
FROM Employee
WHERE #EmpGuid = EmpGuid)
IF (#Password = #CurrentPassword)
UPDATE [Employee]
SET [Password] = #NewPassword
WHERE #EmpGuid = EmpGuid
SELECT 1;
ELSE
SELECT 2;
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
END CATCH
But I really don't know why in my else clause I get
Incorrect syntax near 'ELSE'
What am I doing wrong? Regards
You you want to have more than one statement after the IF, you must use a BEGIN .... END block - like this:
BEGIN TRY
BEGIN TRAN;
DECLARE #CurrentPassword VARCHAR(255) = (SELECT TOP 1 [Password]
FROM Employee
WHERE #EmpGuid = EmpGuid)
IF (#Password = #CurrentPassword)
BEGIN --- you need a *BEGIN* here!!!
UPDATE [Employee]
SET [Password] = #NewPassword
WHERE #EmpGuid = EmpGuid
SELECT 1;
END --- and the *END* for your new *BEGIN*
ELSE
SELECT 2;
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
END CATCH
Use explicitly begin . . end
BEGIN TRY
BEGIN TRAN
DECLARE #CurrentPassword VARCHAR(255) = (SELECT TOP 1 [Password]
FROM Employee
WHERE #EmpGuid = EmpGuid)
IF (#Password = #CurrentPassword)
BEGIN
UPDATE [Employee]
SET [Password] = #NewPassword
WHERE #EmpGuid = EmpGuid
SELECT 1
END
ELSE
BEGIN
SELECT 2
END
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
END CATCH
I would like to declare a variable within an if/else statement in a SQL Server stored procedure. I understand that this is fairly impossible because SQL Server doesn't do memory management with respect to declaration of variables within procedures. Is there a way to have a variable scoped in an if/else statement, then redeclare a variable with the same name in another if/else statement? For example:
create procedure Foo
as
begin
if exists (x)
begin
declare #bob int
set bob = 1
end
else
begin
declare #bob int
set bob = 2
end
end
From books online:
The scope of a variable is the range of Transact-SQL statements that can reference the variable. The scope of a variable lasts from the point it is declared until the end of the batch or stored procedure in which it is declared.
However. Nothing keeps you from doing this:
create procedure Foo as begin
declare #bob int
if exists (x)
begin
set #bob = 1
end
else
begin
set #bob = 2
end
end
No, SQL is pretty funny/weird like that
Declare the variable before the if exists block of code
so
declare #bob int
set #bob = 2
if exists(x)
begin
set #bob = 1
end
Now, take a look at these examples and try to guess what happens
WHILE 1 = 2 --not true of course
BEGIN
DECLARE #VAR INT;
END
SET #VAR = 1;
SELECT #VAR;
This of course works, but it is not initialized every time
DECLARE #loop INT
SET #loop = 0
WHILE #loop <=6
BEGIN
DECLARE #VAR INT
SET #VAR = COALESCE(#VAR,0) + 1
SET #loop = #loop +1
END
SELECT #VAR
is there some reason why you can't do :
declare #bob int
if exists(x)
begin set #bob = 1 end
else
begin set #bob = 2 end
You could resort to using dynamic SQL:
if exists (x)
begin
exec sp_executesql N'
declare #bob int
set #bob = 1
';
end
else
begin
exec sp_executesql N'
declare #bob int
set #bob = 2
';
end
how to remove leading zero from this
number RESULT WOULD BE LIKE THIS
00000.9 .9
A0001.1 A1.1
G0101.3 G101.3
00808.8 808.8
J0000.5 J.5
declare #input varchar(10);
declare #output varchar(10);
set #input = '00000.9';
while ((ISNUMERIC(substring(#input,1,1)) = 0) or (substring(#input,1,1) = '0'))
begin
if substring(#input,1,1) = '0'
begin
set #input = substring(#input,2,len(#input) )
end
else
if ISNUMERIC(substring(#input,1,1)) = 0
begin
set #output = substring(#input,1,1);
set #input = substring(#input,2,len(#input))
end
end
if LEN(#output) > 0
set #input = #output + #input
select #input
#input is your input
ALTER FUNCTION NUMBER(#NUMBER VARCHAR(7))
RETURNS VARCHAR(7)
AS
BEGIN
DECLARE #NUM VARCHAR(1)
DECLARE #NUM1 VARCHAR(7)
SET #NUM= SUBSTRING(#NUMBER,1,1)
IF(#NUM LIKE '[A-Z%]')
BEGIN
SET #NUM1=#NUM+''+CAST(CONVERT(FLOAT,SUBSTRING(#NUMBER,2,7),2)AS VARCHAR(7))
END
ELSE
BEGIN
SET #NUM1=LTRIM(STR(cast(#NUMBER as float),case when len(cast(#NUMBER as float)) > 7 then 7 else len(cast(#NUMBER as float)) end,1))
END
RETURN #NUM
END
I am trying to write a sproc with a transaction. Can anybody tell me if there would be any issues with code below, or if it will work as intended?
ALTER procedure [dbo].[DeleteMetricMeter]
(
#SectionID int,
#MetricMeterID int,
#Result bit output
)
as
declare #MetricMeterCount int
declare #err int
declare #rowcount int
set xact_abort on
begin tran
select #MetricMeterCount = count(*) from luMetricMeters
where fkSectionID = #SectionID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
delete from luMetricMeterList
where pkMetricMeterID = #MetricMeterID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
delete from luMetricMeters
where pkMetricMeterID = #MetricMeterID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
if (#MetricMeterCount = 1)
begin
delete from luMetricSections
where pkSectionID = #SectionID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
end
commit tran
set #result = 1
return #result
on_error:
rollback tran
set #result = 0
return #result
If you are using Sql Server 2005+, I would recomend rather using TRY...CATCH (Transact-SQL) and have a look at section [B. Using TRY…CATCH in a transaction]
This will GREATLY simplify your procedure.
There are a few issues with the procedure:
You should not evaluate rowcount unless it really indicates an error. When there is no data deleted there is no need to rollback.
Your code is not thread safe. The MetricMeterCount query should be changed to this to prevent other threads from performing the delete in between your select & the execution of the delete:
select #MetricMeterCount = count(*)
from luMetricMeters with (xlock, serializable)
where fkSectionID = #SectionID
I would write the code like this:
ALTER procedure [dbo].[DeleteMetricMeter]
(
#SectionID int,
#MetricMeterID int,
#Result bit output
)
as
DECLARE #MetricMeterCount int
DECLARE #err int
DECLARE #rowcount int
SET xact_abort ON
BEGIN TRAN
DELETE FROM luMetricMeterList
WHERE pkMetricMeterID = #MetricMeterID
SELECT #err = ##error
IF (#err <> 0)
GOTO on_error
DELETE FROM luMetricMeters
WHERE pkMetricMeterID = #MetricMeterID
SELECT #err = ##error
IF (#err <> 0)
GOTO on_error
IF EXISTS (SELECT *
FROM luMetricMeters WITH (xlock, serializable)
WHERE fkSectionID = #SectionID)
BEGIN
DELETE FROM luMetricSections
WHERE pkSectionID = #SectionID
SELECT #err = ##error
IF (#err <> 0)
GOTO on_error
END
COMMIT TRAN
RETURN (0)
on_error:
ROLLBACK TRAN
RETURN (-1)
GO
Note: The return values should be 0 for success and a negative number for failure.