multi cursor stored procedure in teradata - sql

I am completely new to sql and teradata(6weeks). and have been given an assignment, which had little instruction.
(Create a stored procedure that allows a user to select a bat’s manufacturer and (optionally) serial number using a stored procedure. The output should display all of the players who use the bat’s manufacturer. If the serial number is also provided, only display the players who use that bat’s manufacturer and serial number. Make sure you use a CREATE PROCEDURE call and insert this procedure into the existing database. ) this is a database through teradata that has been duplicated into my own database to be edited. This is what I got so far and it keeps returning two errors. I'd love help with a solution and best possible recommendation for learning sql quickly and efficiently. I appreciate the help in advance. and i'm sure this is the ugliest code you've seen, I aplogize. :-D
CREATE PROCEDURE batman(manuf varchar(20), bat_type varchar(4)=null)
DYNAMIC RESULT SETS 2
BEGIN
DECLARE c CURSOR FOR
SELECT playernum
FROM affiliation, bats
WHERE manuf = :manuf;
declare serial cursor for
select playernum
from affiliation
where bat_type=NULL or bat_type=:bat_type
if bat_type=NULL then open c
else open serial;
end if;
END;

The default of a parameter is always NULL, no need to declare that.
You can't compare NULLs using =, must be is null instead.
And there are some missing semicolons...
CREATE PROCEDURE batman(manuf VARCHAR(20), bat_type VARCHAR(4))
DYNAMIC RESULT SETS 1
BEGIN
DECLARE c CURSOR FOR
SELECT playernum
FROM affiliation, bats
WHERE manuf = :manuf;
DECLARE serial CURSOR FOR
SELECT playernum
FROM affiliation
WHERE bat_type IS NULL OR bat_type=:bat_type;
IF bat_type IS NULL THEN OPEN c;
ELSE OPEN serial;
end if;
END;

Related

Stored procerudure that calculate number of rows with same number and place that value to other table

I need help with an assignment where I'm supposed to create a Stored Procedure in SQL. I'm new to SQL and it's the first course in databases that I take. I'm using SQL Server Managment Studio 2012.
I have 2 tables, table book, and table bookcopy. Table book has three columns, isbn (the primary key), title and nrOfCopies. The bookcopy table also has three columns, barcode (the primary key), status and isbn( a foreign key that references the isbn-column in table book).
So the assignment is to create a stored procedure for a specific isbn-value (the number of rows with the same isbn-number) that updates the nrOfCopies-column in the book-table. The number of rows for a specific isbn-number will be the value in the nrOfCopies-column for that isbn-number in the book-table.
I tried to do it like this:
CREATE PROCEDURE spNrOfBooks
AS
BEGIN
DECLARE #calcNr AS INT
SET #calcNR = (SELECT COUNT(isbn) FROM bookcopy)
UPDATE book SET nrOfCopies = #calcNr WHERE isbn LIKE (SELECT isbn FROM bookcopy)
END
When I execute this procedure I get an error message (Msg 512).
Can someone please help me by pointing out what I can do to solve this?
If I understand you correct you need a procedure that counts the number of copies for a specific isbn number in table bookcopy, and than updates table book with that count.
If that is the case than it should look something like this.
( I just used varchar(100) for isbn because I dont know how your isbn is defined)
CREATE PROCEDURE spNrOfBooks (#isbn varchar(100))
AS
BEGIN
SET NOCOUNT ON
UPDATE book
SET nrOfCopies = (select count(*) from bookcopy where isbn = #isbn)
WHERE isbn = #isbn
END
you can use it like this
execute spNrOfBooks '12345678901234567'
I would suggest something like this:
CREATE PROCEDURE spNrOfBooks
#isbn VARCHAR(17)
AS
BEGIN
UPDATE B
SET B.nrOfCopies = (
SELECT COUNT(*) FROM bookcopy bc
WHERE bc.isbn=B.isbn
)
FROM book B
WHERE #isbn IS NULL OR B.isbn=#isbn
END;
GO
The procedure could update all nrOfCopies or it could update only the value for a speciffc '#isbn' that is supplied via the parameter.
The OR operator in the WHERE clause could eventually lead to some performance problems according to my experience. This could be avooided by using two SPs (one with and one without the #isbn parameter), or by using an IF clause inside the procedure.
Hope this helps!
This gets you the outcome to need;
CREATE PROCEDURE spNrOfBooks
AS
UPDATE x
SET x.nrOfCopies=xx.CopiesCount
from book x
inner join
(
select
CopiesCount=COUNT(1),
isbn
from
bookcopy
group by
isbn
)xx on x.isbn=xx.isbn

Creating tables - Write a script

Hii ,
I am a bit new to SQL and would like some help to solve the following problem.
I have a database X which contains a table TABLE with column named domain.I retrieve these values and create one database for each value with that value as the database name . For example , if the domain has the values value1, value2, value3 there should be three databases created with names value1 , value2 and value3...and when i add a value to the TABLE in database X , a new database should be created with the value X.TABLE.domainvalue ...
I need to write an SQLScript that accomplishes this.
Any help would be appreciated.
Links that would help me understand better are welcome.
Try this :
CREATE PROCEDURE procCreateDataBase()
BEGIN
DECLARE domainName CHAR(50);
DECLARE cur1 CURSOR FOR SELECT domain FROM databaseX.domainNames;
OPEN cur1;
LOOP
FETCH cur1 INTO domainName;
CREATE DATABASE IF NOT EXISTS domainName;
END LOOP;
CLOSE cur1;
END;
This is a stored procedure you can call anytime and that will create your databases depending on the domains found, if they don't already exist.

Inserting multiple rows with SQL where a record does not exist

I want to insert multiple rows of data into a MySQL database, but only when my order_id field is unique. This is the current query I have, which doesn't work. Lets say a record with an order_id of 2 is already in the table:
INSERT INTO conversion
(user_id,url_id,order_id,sale,commission,transaction_date,process_date)
VALUES (1,1,1,'32',0.3995,'2010-11-15 12:15:18','2010-11-15 12:15:18'),
(3,6,2,'*not-available*',0.001975,'2010-11-15 12:15:18','2010-11-15 12:15:18')
WHERE (order_id <> 3);
Any help is appreciated.
Tom
Solved by using REPLACE.
Example:
REPLACE INTO conversion (user_id,url_id,order_id,sale,commission,transaction_date,process_date) VALUES (1,1,3,'32',0.3995,'2010-11-15 12:50:31','2010-11-15 12:50:31'),(1,2,2,'*not-available*',0.001975,'2010-11-15 12:50:31','2010-11-15 12:50:31');
url: http://dev.mysql.com/doc/refman/5.0/en/replace.html
Thanks all.
INSERT doesn't support the WHERE clause because if you're inserting it implies that the record doesn't currently exist, so therefore there would be nothing for the WHERE clause to look at.
The way to do it in the example you've given is simply not to call the INSERT statement if the order_id field in your insert doesn't match the criteria you want.
If you're calling INSERT multiple times, you'd have some sort of code (either SQL or an external program) which loops through the rows you're inserting; this would be where you'd filter it.
If I am in a similar situation, I would create a stored procedure to handle the logic of figuring out whether an order_id already exists.
--Run this first
--It will create a stored procedure call InsertConversion
--Begin of stored procedure
CREATE PROCEDURE InsertConversion
#user_id int,
#url_id int,
#order_id int,
#sale varchar(5),
#commission money,
#transaction_date datetime,
#process_date datetime
AS
BEGIN
SET NOCOUNT ON;
if not exists(select order_id from conversion where order_id = #order_id)
begin
INSERT INTO conversion(user_id, url_id, order_id, sale, commission, transaction_date, process_date)
VALUES(#user_id, #url_id, #order_id, #sale, #commission, #transaction_date, #process_date)
end
END
GO
--End of stored procedure
Once the store procedure created, you can execute it and pass in the same values as you would pass into an INSERT/VALUES statement:
exec InsertConversion 1,1,1,'32',0.3995,'2010-11-15 12:15:18','2010-11-15 12:15:18'
exec InsertConversion 3,6,2,'*not-available*',0.001975,'2010-11-15 12:15:18','2010-11-15 12:15:18'
If you want to be fancy, you can include a couple of 'print' statement in the store procedure to tell you whether it inserts the record.

Stored procedure return the primary key after insert?

I want a stored procedure to return the primary key of the new record after it gets executed. I think it will be returned by OUT parameter in the procedure. But how to select the newly inserted row ID ? I don't want to use select MAX(row_id) as it is a multi user environment.
Any procedure sample will be appreciated.
My platform is ISeries DB2 V5 R4. Thanks.
Edit
The row id Column is not an identity column. It uses a sequence for the key which gets generated via a trigger before insert on table.
Edit
Here is what I am trying to do
Begin Stored procedure
Insert into Employees;
(row id gets automatically generated by trigger)
Return row id ;
I want to avoid a select in returning row id.
just set the out parameter to the column that contains the PK.
CREATE PROCEDURE DB2TBL.DO_STUFF (IN Param1 INT, IN Param2 CHAR(32),OUT Param3 INT)
/* Param1 is primary key */
LANGUAGE SQL
P1: BEGIN
DECLARE OUTPARAM INT;
/* Do the stored procedure */
SET OUTPARAM = Param1;
--UPDATED---
Hi Popo,
First off could you give more detail on what you mean when you say the rowid is assigned by a trigger?
If you had a real identity column you would use the IDENTITY_VAL_LOCAL() function like this right after the INSERT: SELECT IDENTITY_VAL_LOCAL() INTO myrowid FROM SYSIBM.SYSDUMMY1; I'm not 100% on that syntax because I generally use embedded SQL and it works differently there so you might have to play with it. IBM documentation is at http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/index.jsp?topic=/db2/rbafzscaidentity.htm.
However since you are doing something more complicated, I think this alternate method might work. You'll need to re-format your INSERT to be wrapped in a SELECT.
SELECT myrowid
INTO myrowid
FROM FINAL TABLE (
INSERT INTO myfile (myrowid, other_stuff) VALUES (default, 'blah')
)
You'll need to adjust for the proper field names and so on but I think this will do the trick. There's not much documentation but if you want to see it go to http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/index.jsp?topic=/db2/rbafzbackup.htm and scroll all the way down to the bottom of the page.
Cheers
CREATE PROCEDURE ASF_InsertNewAuthorRequest
(IN #REQUESTTYPE CHAR(1), IN #UserID VARCHAR(18), IN #DATECREATED TIMESTAMP, IN #REQUESTSTATUS CHAR(1))
LANGUAGE SQL
DYNAMIC RESULT SETS 1
P1: BEGIN
DECLARE cursor1 CURSOR WITH RETURN for
SELECT IDENTITY_VAL_LOCAL FROM SYSIBM.SYSDUMMY1;
INSERT INTO AFS_REQUEST
( REQUESTTYPE, "UserID", DATECREATED, REQUESTSTATUS )
VALUES
( #REQUESTTYPE, #UserID, #DATECREATED, #REQUESTSTATUS );
OPEN cursor1;
END P1
INSERT INTO [User] (columns)
OUTPUT inserted.userId
VALUES (#values)
This will return the newly created userId column value... very simple.

SQL stored proc - help me write this one, please! (part 2)

I have the following table with the value 501 in it..
CREATE TABLE _Numbers(
Number numeric(20,0) NOT NULL PRIMARY KEY
)
INSERT INTO _Numbers VALUES(501)
How can I write a stored proc on this which returns me 501 and increments Number to next in sequence (i.e. 502)? I would like this behaviour repeated every time the stored proc is called.
(Also, how can I call this stored proc from any query?)
Part of my previous question 3151056.
Thanks,
Voodoo
Use an IDENTITY column which takes care of numbering and incrementing for you.
Any returned number is liable to be already used by another connection/client/process
You're importing data from old tables, right?
What if you import data from old tables with identity off and after that you set the identity with the highest number+1 and continue your life using identity.
Other approach is using a trigger at insert that would check if NumberItem is null and it will add the Max+1 if it's null. If not, do nothing.
I don't think that SP is a good solution. And I'm pretty sure you don't need all that stuff.
CREATE OR REPLACE PROCEDURE read_and_increment (number_just_read OUT NUMBER)
IS
BEGIN
DECLARE
stored_number NUMBER DEFAULT NULL;
BEGIN
SELECT number
INTO stored_number
FROM _numbers
WHERE ROWNUM = 1;
number_just_read := stored_number;
UPDATE _numbers
SET number = number + 1;
COMMIT;
END;
END read_and_increment;