Having a hard time creating a procedure in SQL - mysql

I need to create a procedure for class, but I think the sql version in the book is VERY old. For example, I don't think I can't use "Create or replace" like the book says, but "create", "drop", "create", but that is beyond the scope.
My issue is that I am having trouble setting the %TYPE. I use WAMP, I created the procedure in Notepad++, and pasted it to the console. I then opened up phpmyadmin, pasted it into the query window, and was rewarded with more verbose error message. Book: "A guide to SQL" by Phil Pratt and Mary Last, Ninth Edition https://www.amazon.com/Guide-SQL-Philip-J-Pratt/dp/111152727X . Book has TAL Distributers, SOLARIS comdominium group, and COLONIAL adventure tours databases it that helps anyone. The instructor provided the sql file to create the databases as a time saver. This is for the last chapter, ch.8 Creation code:
delimiter ;;
use tal;;
CREATE PROCEDURE CHANGE_ITEM_PRICE(I_ITEM_NUM IN item.item_num%TYPE, I_NEW_PRICE IN item.price%TYPE) AS
BEGIN
UPDATE item SET price = I_NEW_PRICE
WHERE item_num = I_ITEM_NUM;
END;;
delimiter ;
2 Errors:
Unrecognized data type. (near "IN" at position 56)
and another for position 91.
Any thoughts? I'm not looking to be spoon fed here, I just need a little guidance please.
Edit: Thank you #Bill Karwin. The corrected working syntax follows:
delimiter ;;
use tal;;
CREATE PROCEDURE CHANGE_ITEM_PRICE(IN I_ITEM_NUM char(4), IN I_NEW_PRICE decimal(6,2))
BEGIN
UPDATE item SET price = I_NEW_PRICE
WHERE item_num = I_ITEM_NUM;
END;;
delimiter ;

I_ITEM_NUM IN item.item_num%TYPE
This is not a valid procedure argument declaration for MySQL. You have to name the type with something like INT or DATE or VARCHAR(length) or another known type. MySQL has no syntax like you show to dynamically query the type of a named column.
Out of curiosity, where did you get that syntax? Is it part of some other brand of SQL database? I've never seen it before.
Aha, I found it:
https://www.postgresql.org/docs/current/static/sql-createfunction.html says:
The type of a column is referenced by writing table_name.column_name%TYPE. Using this feature can sometimes help make a function independent of changes to the definition of a table.
That's in the PostgreSQL documentation. PostgreSQL and MySQL are not the same software, and there are many examples of syntax and features that each has that the other does not.
This syntax is also supported by Oracle: %TYPE attribute. Actually, I assume Oracle did it before PostgreSQL.
Re your comment:
var IN char(4)" does not work either
You said you were interested in a little guidance. The simplest guidance is that when you're learning a new syntax, it helps to read the reference documentation. :-)
I've used MySQL a lot over the past 16 years. I am a regular speaker at MySQL Conferences and users' groups. I'm a published author. And even I open the documentation pages as a first step when I'm doing something that isn't immediately familiar to me.
Here: http://dev.mysql.com/doc/refman/5.7/en/create-procedure.html
Notice when declaring procedure parameters, it's IN param_name type, not param_name IN type.
now the error is "syntax near ' AS....'
Again, refer to the documentation. There's no AS in the stored procedure syntax for MySQL. That's also Oracle syntax.
You may need to get a different book if you're going to use MySQL instead of Oracle. For example, I suggest MySQL Stored Procedure Programming: Building High-Performance Web Applications in MySQL.
But honestly, I am not a fan of using stored procedures in MySQL at all. MySQL's implementation of stored procedures is far inferior to that of Oracle. MySQL procedures have no packages or libraries, there's no procedure debugger, they're not compiled, and they don't scale well.
Most developers who use MySQL put more logic in their application code instead of stored procedures. This allows them to scale out their performance to numerous application servers, instead of piling up the load on the database server.

I don't believe MySQL has an equivalent for Oracle's %TYPE operator. You will need to specify the data types directly, for example:
CREATE PROCEDURE CHANGE_ITEM_PRICE(I_ITEM_NUM INT, I_NEW_PRICE DECIMAL) ...
I checked through the function and operator list in the most recent MySQL manual to see if they have recently added this function, but did not find it there.

Related

Stored procedure returning values: bug, artefact, undocumented feature?

I couldn't help noticing that stored procedures are able to return values:
create table foo(foo int);
insert into foo values (42);
create procedure get_foo() select * from foo;
call get_foo();
+------+
| foo |
+------+
| 42 |
+------+
More intriguing, wrapper such as python's MySQLdb do pass through the procedure's output to the caller.
However, no such behavior is documented. The documented way to get results out of the procedure is using OUT procedure arguments. I find this return value of stored procedure hardly used or indeed mentioned anywhere, yet it seems to be a useful behavior.
My question is, is this an artifact of stored procedures, or is it implemented on purpose but undocumented for some reason? How long has it been so, and can one rely on it?
(I tested on MariaDB 10.3 and don't know how this extends to MySQL as well).
This is the way stored procedures are designed to work in MySQL, since they were introduced circa 2005.
https://dev.mysql.com/doc/refman/8.0/en/stored-routines-syntax.html
MySQL supports a very useful extension that enables the use of regular SELECT statements (that is, without using cursors or local variables) inside a stored procedure. The result set of such a query is simply sent directly to the client. Multiple SELECT statements generate multiple result sets, so the client must use a MySQL client library that supports multiple result sets.
I couldn't find a similar statement in the MariaDB documentation on stored procedures. I can't explain why they didn't choose to document this feature. As far as I know, they have not changed it since they forked from MySQL in 2010.
Since the first implementation (afaik it was in MySQL 5.0, written by Per Erik Martin), stored procedures in MariaDB/MySQL were able to return result sets.
It is very well documented in both MySQL and MariaDB documentation which kind of SQL statements are not supported.
Please also note, that not only a SELECT but also an INSERT might return a result set.

"PROCEDURE ANALYSE" analogues in MySQL 8 and PostgreSQL

In older versions of MySQL there was an option to analyze existing tables:
SELECT * FROM `table_name` PROCEDURE ANALYSE()
That seemed useful, a developer could analyze existing tables, see recommendations (for example use smallint instead of int) and consider some of them.
In MySQL 8.0 PROCEDURE ANALYSE() was removed. The reason I found:
"Reasoning: it was discussed many times that the PROCEDURE ANALYZE
syntax is an anachronism and almost unused non-standard syntax
extension".
Is this the only reason or analyzing tables automatically is a bad practice (even as just an additional instrument for analyze)?
Also I can't find any analogue of "Procedure Analyse" in Postgresql.
I know that I can analyze queries, but I suppose that it is useful to analyze table structure to consider it in architecture of new tables.
This feature is gone and no clear successor that I can find is provided or referenced in the documentation. I attempted to email the guy responsible for this, he no longer works at MySQL and his personal email is dead, so maybe his work was cut short. It's a shame they removed PROCEDURE ANALYSE that users relied on without providing a replacement stored procedure that they talked about.
One can analyse tables manually with statements such as:
select MAX(LENGTH(address1)) from places;
select address1 from places where length(address1) > 99;

is there a type definition similar to the oracle rowtype in mysql

I am developing a procedure where I need to insert all the columns of one table to another table including other calculation.
I have to fetch record by record, manipulate it and transfer it to another table.
is there a type definition similar to the oracle rowtype in mysql???
Any help like example or any link will be very helpful to me.
Thanks in advance...
No, there is nothing similar. You have to declare a single variable for each column to fetch
(http://www.mssqlforums.com/fetching-entire-row-cursor-t93078.html).
See this post for an example of how to use cursors in SQL-Server: Get Multiple Values in SQL Server Cursor
EDIT: sorry Miljen Mikic, my bad - but for mysql applies the same:
see this post: Conversion of Oracle %ROWTYPE to MySQL
MySQL has no an equivalent of Oracle %ROWTYPE. In MySQL it is necessary to declare a variable for every column.
Unfortunately, no ROWTYPE or the like behaviour on MySQL. Perhaps in a future, but in 2022 this feature remains not developed.
So we must continue declaring tons of variables in order to manage cursor data... :`(
See related link on MySQL dev forum at High Level Architecture tab

SQL Server sp_help : how to limit the number of output windows

Normally successful execution of
sp_help [object_name]
in SQL Server returns a total of 7 output windows with various results out of which normally I am interested in only 2 windows namely the one with all the column information and the one with the constraints.
Is there a way I can tell SQLserver to only display these while formulating the command?
Short answer: no, you can't do this directly because the procedure is written to return that data, and TSQL has no mechanism for accessing specific result sets.
Long answer: but you can easily get the same information from other procedures or directly from the system catalog:
sp_columns, sp_helpconstraint (this is actually called by sp_help) etc.
sys.columns, sys.objects etc.
There's also the option of copying the source code from sp_help and using it as the basis of a new procedure that you create yourself, although personally I would just write it myself from scratch. If you do decide to write your own stored proc, you might find this question relevant too.

Can stored procedure in MySql 5.0.x be encrypted?

In Microsoft Sql it is possible to encrypted stored procedures with
CREATE PROCEDURE dbo.foo
WITH ENCRYPTION
AS
BEGIN
SELECT 'foo'
END
This stops people looking at stored procedures code.
How can I do this in MySql 5.0.x ?
You can not do this in MySQL. See bug #4210.
[Edit]: The comment from Leonidas on another answer to this question needs to be out there for anyone to read, so I'm quoting it here:
Obfuscation can be reversed. I found
at least one product via Google, that
promises to reveal the SP-code. So I
think/hope that the MySQL-team won't
bother with "security by obscurity" or
even worse "intellectual asset
protection" (as described in the bug
4210).
It looks like its been requested before but I don't know if they're considering it.