i have a stored procedure which first of all checks for some record whether it exists or not. if already exists then executes updates statement (if update statement works fine then returns affected row no else returns a variable with -1000 value) else it selects a variable with value -2000.
Problem is it works fine if i executes it in sql server but when i call it from C# then it returns current_indent('') or only -1 no -1000 or -2000 is returned.
USE [youfuntube]
GO
ALTER PROCEDURE [dbo].[usp_change_pass]
#e_mail varchar(60),
#old_pass varchar(27),
#new_pass varchar(27)
AS
BEGIN
declare #exist int;
Set #exist =0;
Select #exist=COUNT( userinfo_signup.e_mail) from userinfo_signup where userinfo_signup.e_mail=#e_mail;
if(#exist>0)
BEGIN
SET #exist=0;
SELECT #exist= COUNT ( userinfo_signup.e_mail) from userinfo_signup Where userinfo_signup.e_mail=#e_mail And userinfo_signup.password=#old_pass;
if(#exist>0)
Begin
UPDATE userinfo_signup
Set password=#new_pass
Where e_mail=#e_mail AND password=#old_pass;
Select IDENT_CURRENT( 'userinfo_signup');
End
ELSE
begin
Set #exist=-1000;
SELECT #exist;
end
END
ELSE
BEGIN
SET #exist=-2000;
Select #exist;
END
END
GO
I would try using the MERGE command instead of an if exists. Here is a simple introduction to the command: http://blog.sqlauthority.com/2008/08/28/sql-server-2008-introduction-to-merge-statement-one-statement-for-insert-update-delete/
Related
i have a pl/sql procedure to modify/delete records based on a checkbox selection in my Apex application:
delete from s_objectif_operation where id_operation=:p124_id_operation;
for a in (select distinct id from s_objectif
where id in (
SELECT trim(regexp_substr(:P124_S_OBJECTIF, '[^:]+', 1, LEVEL)) str
FROM dual
CONNECT BY instr(:P124_S_OBJECTIF, ':', 1, LEVEL - 1) > 0
))
loop
insert into s_objectif_operation
(id_s_objectif, id_operation)
values
(a.id, :p124_id_operation);
end loop;
for every modification, this procedure deletes all the records and insert the correct ones back so i had to remove the "cascade on delete" option the foreign key constraint to suspend any child record removal but now the procedure is not working.
maybe "raise an exception" can work?
There is no need to delete all the records and re-inserting only the checked ones. That is a brute force approach and it works but it does not capture the real user action.
As an alternative you can just delete/insert the changes. To do that, create an additional page item P124_S_OBJECTIF_OLD and set it to the value P124_S_OBJECTIF with a computation after header (or any pre-rendering processing point after P124_S_OBJECTIF has been initialized). In your pl/sql code use APEX_STRING.SPLIT to process the checkbox values and the MULTISET operator to decide which values have been touched.
Then your pl/sql process code could look like this.
DECLARE
l_objectif_old apex_t_varchar2;
l_objectif_new apex_t_varchar2;
l_objectifs_added apex_t_varchar2;
l_objectifs_removed apex_t_varchar2;
BEGIN
l_objectif_old := apex_string.split(:P124_S_OBJECTIF_OLD,':');
l_objectif_new := apex_string.split(:P124_S_OBJECTIF,':');
l_objectifs_added := l_objectif_new MULTISET EXCEPT l_objectif_old;
l_objectifs_removed := l_objectif_old MULTISET EXCEPT l_objectif_new;
-- add new
FOR i IN 1 .. l_objectifs_added.COUNT LOOP
INSERT INTO s_objectif_operation (id_s_objectif, id_operation)
VALUES (l_objectifs_added(i), :P124_ID_OPERATION);
END LOOP;
-- delete old
FOR i IN 1 .. l_objectifs_removed.COUNT LOOP
BEGIN
DELETE FROM s_objectif_operation
WHERE id = l_objectifs_removed(i);
EXCEPTION WHEN OTHERS THEN
-- this will fire if there are child records. Add your own code.
NULL;
END;
END LOOP;
END;
Note that you might have to tweak the insert and delete statement to match your data structure.
I'm trying to create a trigger in which, only under certain circumstances, an insert is performed on another table. Consider the following code:
create table journal (
pk integer primary key autoincrement,
dsc varchar(10) not null
);
create table users (
name varchar(30) primary key not null
);
create trigger users_ai
after insert on users
begin
select
case
when 1 then
insert into journal(dsc) values('foo')
end;
end;
I get the following error when I run this code:
Error: near line 10: near "insert": syntax error
In production, the "1" in the when clause would be replaced by a more complex expression. I've also tried "true" and get the same results. I've also tried surrounding the insert statement in parens and get the same results. Any ideas how to accomplish what I want?
If you look at the syntax diagram for "CREATE TRIGGER", you'll see your attempt just doesn't match. You can, however, simply use the WHEN branch (without needing FOR EACH ROW):
create trigger users_ai
after insert on users
when 1 begin
insert into journal(dsc) values('foo');
end;
OK, figured it out. Instead of putting a conditional expression in the block of the trigger, I used a when clause. Here's the code that works:
create trigger users_ai
after insert on users when 1
begin
insert into journal(dsc) values('foo');
end;
If that when expression is changed to something that returns false (say 0) then the insert isn't done. In production, the expression will sometimes return true, sometimes false, which, of course, is the point of this code. Thanks everybody!
I think that you want a CASE statement, not a CASE expression.
create trigger users_ai after insert on users
begin
case
when ... then insert into journal(dsc) values('foo');
when ... then ...;
else ...;
end case;
end;
Note: if your trigger needs access to the data that was just inserted, its definition should the for each row option.
You can try to use an INSERT ... SELECT and your expression in the WHERE clause.
...
INSERT INTO journal
(dsc)
SELECT 'foo'
WHERE 1 = 1;
...
1 = 1 needs to be replaced by your Boolean expression.
I have a stored procedure I've started coding and need to return a value. In SQL Server I could just do a SELECT of the variable to return it. However this does not seem to work with Teradata and have not found a similar example on how to do this. Here is my stored procedure:
REPLACE PROCEDURE sp_Get_MyValue()
BEGIN
DECLARE mytestvar VARCHAR(40);
SELECT mycolumn INTO mytestvar FROM MyTable;
SELECT mytestvar;
END;
I get this error:
STATEMENT 2: REPLACE failed. Failed [5526 : HY000] Stored Procedure
is not created/replaced due to error(s).{Nested Failure Msg [5526 :
HY000] SPL1045:E(L10), Invalid or missing INTO clause.}
I also tried adding an OUT variable to the procedure but that did not work either:
REPLACE PROCEDURE sp_Get_MyValue(mytestvarout VARCHAR(40))
BEGIN
DECLARE mytestvar VARCHAR(40);
SELECT mycolumn INTO mytestvar FROM MyTable;
END;
With this error:
Executed as Single statement. Failed [5531 : HY000] Named-list is not
supported for arguments of a procedure. Elapsed time = 00:00:00.079
To return a single row you must define and OUT-variable and assign a value to it:
REPLACE PROCEDURE sp_Get_MyValue(OUT mytestvarout VARCHAR(40))
BEGIN
DECLARE mytestvar VARCHAR(40);
SELECT mycolumn INTO mytestvar FROM MyTable;
SET mytestvarout = mytestvar;
END;
To return a result set you need to define a kind of dummy-cursor (blame Standard SQL :-)
Returning Result Sets from a Stored Procedure
When I am running this Netezza stored procedure, I am getting an error
attribute 'SOME_VALUE' not found
As per requirement I have to get value from one table (TABLE_A) and insert into another table (TABLE_B).
This is the procedure:
create or replace procedure my_proc()
returns boolean
execute as owner
language NZPLSQL
as
BEGIN_PROC
declare rec RECORD ;
BEGIN
for rec in SELECT * from TABLE_A loop
EXECUTE IMMEDIATE
'INSERT INTO TABLE_B(COLUMN_B)
values( '|| rec.COLUMN_A_OFTABLE_A || ')';
END LOOP;
END;
END_PROC;
execute my_proc()
Here below, I am able to insert a string. But I need to insert different value depending on other table as I mentioned above.
EXECUTE IMMEDIATE 'INSERT INTO TABLE_B(COLUMN_B) values( ''Y'');';
When building a string that you are going run EXECUTE IMMEDIATE against, you have be careful to have everything quoted properly. In your case it's thinking that it needs to treat SOME_VALUE as an attribute/column, and it can't any column with that name.
Wrap your column reference in quote_literal() and it will interpret the contents of your column and quote-escape it properly for you.
create or replace procedure my_proc()
returns boolean
execute as owner
language NZPLSQL
as
BEGIN_PROC
declare rec RECORD ;
BEGIN
for rec in SELECT * from TABLE_A loop
EXECUTE IMMEDIATE
'INSERT INTO TABLE_B(COLUMN_B)
values( '|| quote_literal(rec.COLUMN_A_OFTABLE_A) || ')';
END LOOP;
END;
END_PROC;
You can find some more information in the documentation here.
Note: I am assuming that you have some more complicated logic to implement in this stored procedure, because looping over row by row will be much, much slower that insert..select. Often by an order of magnitude.
I am working on Oracle 11g Db, Having trouble on writing Oracle syntax.
I am trying to pass a number variable to my select query and populate the select query to a cursor.
Declare yr_nr NUMBER;
Begin
yr_nr := 2014;
SELECT DCD.CCY ID, DCD.CCYCDDSC DSC
FROM CCYDCD DCD, CCYEXC EXC
WHERE DCD.CCY = EXC.CCY
AND EXC.YEARNR = yr_nr
End
This select query returns 80 records. How to rewrite this syntax.
Ok, so what you have here is an anonymous block and everything that happens in the block stays in that block. Kinda like Vegas.
In other words there is nothing to handle the result set from your query. When you do this:
declare
[varName] [type]
begin
select foo from bar where column = var ; <--- this has no place to go!
end
When you are at an sqlPlus prompt, sqlPlus has a default record set handler which then processes the returned record set and prints it to the screen.
When you use any third party tool like JDBC or Oracle's own OCI library those provide a record set handler then parse them to you with the appropriate calls to get the data, e.g.:
rs.getInteger([query],[column] ) //which returns the specific value.
That anonymous block is essentially a stored procedure. So you have to have something to do with the result set. This is the cause of the missing "into" error you are getting.
If on the other hand you did something like:
declare
[varName] [type]
result number ;
begin
select count(foo) into result from bar where column = var ;
end
The variable result would have the value of 80 since that is the number of records fetched.
declare
[varName] [type]
cursor thisCursor(p1 in number ) is select foo from bar where column = p1 ;
begin
for rec in thisCursor(varName) loop
If rec.column = [some value] then
doSomething
end if ;
end loop ;
end
Do this would allow you to do something with the result set.