I have created a table in HSQLDB with the below structure
CREATE TABLE salary (
emp_no INT NOT NULL,
salary_amount INT NOT NULL,
bonus INT NOT NULL,
PRIMARY KEY (emp_no)
);
and stored procedure below
CREATE PROCEDURE add_bonus_by_emp_no(IN EMP_KEY integer, IN ADDL_BONUS integer)
BEGIN
UPDATE salary
SET bonus = ADDL_BONUS + bonus
WHERE emp_no=EMP_KEY;
Getting error when i run this command, getting error
unexcepted token UPDATE required:ATOMIC : line:2/Error code-5581/42581
Thanks,
The message means you must use BEGIN ATOMIC. See the examples in the Guide for the other additions you need to make:
http://hsqldb.org/doc/2.0/guide/sqlroutines-chapt.html#src_psm_vars
Related
I migrated my company database from MySQL to another hosting firm not knowing the hosting firm uses MariaDB, upon try to create my stored procedure with my IN parameter, MariaDB is seeing the parameter as a columnn. See the stored procedure code below with the error :
CREATE PROCEDURE ADD_WITHDRAWAL_A(IN withdrawalcode_p VARCHAR(25), IN id_p VARCHAR(8), IN amount_p VARCHAR(12), IN datewithdrawn_p VARCHAR(35), IN approved_p VARCHAR(8))
START TRANSACTION;
INSERT INTO Withdrawals(WithdrawalCode, IDD, Amount, DateWithdrawn, Approved)
VALUES (withdrawalcode_p, id_p, amount_p, datewithdrawn_p, approved_p);
UPDATE account SET AccountBalance = AccountBalance - amount_p WHERE IDD = id_p LIMIT 1;
COMMIT;
***** AFTER RUNNING THE ABOVE CODE, MARIADB GAVE THIS ERROR :
Error
SQL query:
INSERT INTO WithdrawalRequest( WithdrawalCode, IDD, Amount, DateWithdrawn, Approved )
VALUES (withdrawalcode_p, id_p, amount_p, datewithdrawn_p, approved_p);
MySQL said: Documentation
#1054 - Unknown column 'withdrawalcode_p' in 'field list'
The column name is WithdrawalCode and not 'withdrawalcode_p', 'withdrawalcode_p' is a parameter passed in to the stored procedure but the server is seeing it as a field name. I spoke with the hosting firm and they said their database is MariaDB and not MySQL. This same code worked in MySQL server.
I will appreciate any useful help rendered here.
You forgot to set non-default delimiters and to wrap the procedure body into BEGIN/END, which is necessary since it has more than one statement.
What happens in your case is that the procedure created with body START TRANSACTION, and the rest is considered to be a set of ordinary statements. Instead, try
DELIMITER $$
CREATE PROCEDURE ADD_WITHDRAWAL_A(IN withdrawalcode_p VARCHAR(25), IN id_p VARCHAR(8), IN amount_p VARCHAR(12), IN datewithdrawn_p VARCHAR(35), IN approved_p VARCHAR(8))
BEGIN
START TRANSACTION;
INSERT INTO Withdrawals(WithdrawalCode, IDD, Amount, DateWithdrawn, Approved)
VALUES (withdrawalcode_p, id_p, amount_p, datewithdrawn_p, approved_p);
UPDATE account SET AccountBalance = AccountBalance - amount_p WHERE IDD = id_p LIMIT 1;
COMMIT;
END $$
DELIMITER ;
I tried implementing a call to Stored proc and the proc returns ID which will used later.
Everytime I execute I get the out parameter as -1. Below is my sample code:
OleDbCommand sqlStrProc = new OleDbCommand();
sqlStrProc.Connection = dbConn;
sqlStrProc.CommandText = "dbo.insert_test";
sqlStrProc.CommandType = CommandType.StoredProcedure;
sqlStrProc.Parameters.Add("#p_TestID", OleDbType.Integer, 255).Direction = ParameterDirection.Output;
sqlStrProc.Parameters.Add("#p_TestName", OleDbType.VarChar).Value = "Test";
sqlStrProc.Parameters.Add("#p_CreatedBy", OleDbType.VarChar).Value = "Test";
int personID = sqlStrProc.ExecuteNonQuery();
Row.outPersonID = personID;
personID is always -1. What am I doing wrong here. Please help..!!
Below is the stored proc code
CREATE PROCEDURE [dbo].[INSERT_TEST]
#p_TestID int OUTPUT,
#p_TestName varchar (50),
#p_CreatedBy varchar (100)
AS
SET NOCOUNT ON
INSERT INTO Test(
TestName,
CreatedBy)
VALUES
( #p_TestName,
#p_CreatedBy)
SELECT #p_TestID = SCOPE_IDENTITY()
-1 could mean that the stored procedure failed to execute as desired and the transaction was rolled back. You may want to look for any truncation issues since you have different sizes for the 2 input parameters but are using the same input. Also I assume you have proper code to open and close connections etc?
-1 returned value is an error produced during the execution of your SP, this is due to the following reasons:
SP Structure: everytime you are executing the SP it tries to create it again while it already exists. so you have to either make it an ALTER PROCEDURE instead of CREATE PROCEDURE or do the following:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[INSERT_TEST]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[INSERT_TEST]
GO
CREATE PROCEDURE [dbo].[INSERT_TEST]
#p_TestID int OUTPUT,
#p_TestName varchar (50),
#p_CreatedBy varchar (100)
AS
Database Connection (Table Name and Location): you have to specify withe the OLEDB the ConnectionString that connects you to the write DB. try to test the full Table path; like the following;
INSERT INTO [DATABASENAME].[SHCEMA].[TABELNAME](
Name,
CreatedBy)
VALUES
( #p_TestName,
#p_CreatedBy)
Define your SP as :
CREATE PROCEDURE [NAME]
AS
BEGIN
END
thought it is not a problem, but it is a proper way to write your SPs in terms of connection transactions,
Let me know if it works fine with you :)
Regrads,
S.ANDOURA
I'm using Firebird 2.x and I have made a stored procedure to insert a record if it doesn't exist and return its ID into a variable.
But when I execute, it turns out that the following error occurs:
Dynamic SQL Error. SQL error code = -104. Unexpected end of command - line 2, column 76.
Full source code of my SP following:
CREATE PROCEDURE INSERT_ADMIN_OFFICE
AS
DECLARE VARIABLE OFF_ID BIGINT;
DECLARE VARIABLE PER_ID BIGINT;
DECLARE VARIABLE EMP_ID BIGINT;
DECLARE VARIABLE AP_ID BIGINT;
BEGIN
IF (NOT EXISTS(SELECT * FROM OFFICE OFF WHERE OFF.DESCRIPTION LIKE '%Administrador%')) THEN
INSERT INTO OFFICE (DESCRIPTION) VALUES ('Administrador') RETURNING ID INTO :OFF_ID;
ELSE
SELECT OFF.ID FROM OFFICE OFF WHERE OFF.DESCRIPTION LIKE '%Administrador%' INTO :OFF_ID;
INSERT INTO PERSON (NAME, BIRTH_DATE, ADDRESS, DISTRICT, CITY, STATE) VALUES ('Intellitools Desenvolvimento de Software Ltda.', '01/01/2007', 'Rua Nunes Machado, 472 - Cj 503', 'Centro', 'Curitiba', 'PR') RETURNING ID INTO :PER_ID;
INSERT INTO USER_PASSPORT (PERSON_ID, USER_NAME, PWD, TYPE) VALUES (:PER_ID, 'intellitools', 123, 1);
INSERT INTO EMPLOYEE (OFFICE_ID, PERSON_ID) VALUES (:OFF_ID, :PER_ID) RETURNING ID INTO :EMP_ID;
INSERT INTO ACCESS_PROFILE (DESCRIPTION) VALUES ('Administrador Geral') RETURNING ID INTO :AP_ID;
INSERT INTO REL_EMPLOYEE_ACCESS_PROFILE (EMPLOYEE_ID, ACCESS_PROFILE_ID) VALUES (:EMP_ID, :AP_ID);
SUSPEND;
END
;
I notice that this error is because of the INTO on the INSERT but I can't find another way to do that.
I appreciate your help!
Just remove SUSPEND and your proc will execute like a charm. For a one time actions I would suggest EXECUTE BLOCK instead of creating stored procedure.
I cannot run the following SP
CREATE PROCEDURE SP_NYANSAT(
FORNAVN VARCHAR(30),
EFTERNAVN VARCHAR(30),
ADRESSE VARCHAR(50),
POSTNUMMER CHAR(4),
TELEFONNUMMER CHAR(8),
EMAIL VARCHAR(50))
AS
DECLARE VARIABLE ID INTEGER;
BEGIN
ID = GEN_ID(GEN_ANSAT_ID,1);
INSERT INTO MYTABLE (ID, FORNAVN, EFTERNAVN, ADRESSE, POSTNUMMER, TELEFONNUMMER, EMAIL) VALUES (:ID, :FORNAVN, :EFTERNAVN, :ADRESSE, :POSTNUMMER, :TELEFONNUMMER, :EMAIL);
END
The error I get is the following:
can't format message 13:896 -- message file C:\Windows\firebird.msg not found.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 3, column 1.
CREATE.
Have you used Set Term before and after this code?
All commands in Firebird must be terminated with a semi-colon. If you want to create a stored procedure you need to be able to distinguish between the terminating semi-colon from the semi-colons inside the stored procedure.
Something like this:
SET TERM ^ ;
CREATE PROCEDURE SP_NYANSAT(
FORNAVN VARCHAR(30),
EFTERNAVN VARCHAR(30),
ADRESSE VARCHAR(50),
POSTNUMMER CHAR(4),
TELEFONNUMMER CHAR(8),
EMAIL VARCHAR(50))
AS
DECLARE VARIABLE ID INTEGER;
BEGIN
ID = GEN_ID(GEN_ANSAT_ID,1);
INSERT INTO MYTABLE (ID, FORNAVN, EFTERNAVN, ADRESSE, POSTNUMMER, TELEFONNUMMER, EMAIL) VALUES (:ID, :FORNAVN, :EFTERNAVN, :ADRESSE, :POSTNUMMER, :TELEFONNUMMER, :EMAIL);
END
^
SET TERM ; ^
Please notice how the declaration of the stored procedure is terminated with ^, thus ending the statement. After the declaration you also restore the terminating semi-colon.
On a side note, I would recommend to copy firebird.msg to the location the error you get tells you so you can see what is really happening.
EDIT:
If you wish you can check this link. There you can find a lot of information regarding Firebird + IBExpress, including SET TERM (page 81).
EDIT 2:
Just tried at home with IBExperts + Firebird and I had no problem creating the stored procedure. My guess is you are trying to do one of the following things:
You have opened an SQL editor and are trying to compile the code directly. That will not work because IBExperts thinks you are trying to run DSQL sentences. Stored procedures are created with PSQL sentences.
You are trying to use the "New procedure" utility (check buttons in the upper right side of the main menu) and pasted the whole code into the editor. That will not work because in that editor you only have to put the body code. Stored procedure name is set in a field on the upper right side of the window you opened. Parameters and variables are introduced by using the "Insert Parameter/Variable" button on the left side above the code editor. The SET TERM sentences are created automatically by IBExperts. You can check the resulting code in the DDL tab.
HTH
I have a stored procedure which
returns a result set with the error
message, when an error occurs. If it
executes without any error, the result
set is empty (Command(s) completed
successfully)
On the vb6 side, I execute the sp and
check whether there is an error by
If Err <> 0 Then
' do sth
End If
But, when there is a result set, the
Err is always 0.
How should I handle this situation?
Sorry for inadequate explanation.
Here are my scripts:
--my sample table
create table #InvoiceDocument (InvoiceID int, ItemID int, Price float, DocStatus bit)
--my test values
insert into #InvoiceDocument (InvoiceID, ItemID, Price)
values (1, 1, 2.5), (1, 2, 5.0), (1,5, null)
--my sample procedure
create procedure sp_ApproveInvoice #InvoiceID int
as
begin
set nocount on
select * into #temp
from #InvoiceDocument
where Price is null and InvoiceID = #InvoiceID
if exists (select 1 from #temp)
begin
select InvoiceID, ItemID, Price from #temp
RAISERROR ('There are non priced items. Invoice can not be approved!',16, 1)
return
end
update #InvoiceDocument
set DocStatus = 1
where InvoiceID = #InvoiceID
end
when I execute this:
sp_ApproveInvoice 1
It both generates a resultset (Results), and an error message (Messages).
On the vb6 side, vb6 can not catch the error here.
You need to RAISERROR in the stored proc to set the error.
Or use output parameters. Or the RETURN statement
Or add logic to distinguish "success" and "fail" recordsets in the client code.
Currently, Err has no meaning because there is no error state
Personally, I use RAISERROR as per my question here with this template
Your particular case cannot be caught with Err since your stored procedure is not generating any error in the traditional sense---it's either giving an empty result set or a normal result set. How can VB know the semantics of a non-empty result set?
For this to work, you either need to change your stored procedure to raise error OR you need to check the result set returned by the stored procedure directly in your code (nothing to do with Err).