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.
Related
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;
Summary: Can DELETE from mysql.proc be used safely from MySQL 5.7 onward?
In question Drop all stored procedures in MySQL or using temporary stored procedures, it was mentioned that in MySQL it is not possible to use DROP PROCEDURE inside a stored procedure (mysql error code 1357, "Can't drop or alter a %s from within another stored routine").
Empirically:
DELETE from mysql.proc WHERE db = <db-name> AND name LIKE '<procedure-prefix>%';
does seem to work fine instead.
In a comment, the question was asked (but not answered):
Is mysql.proc still a viable method of interacting with MySQL meta information in 5.7?
Even though I fully realise it is not "desirable", is it "OK" to use this in MySQL 5.7? Or, is there some vital stuff which DROP PROCEDURE does, such that I must not use this workaround?
The direct delete from the procs table does not seem to take an immediate effect in the current MySQL session.
The flush statement is used in MySQL to make the server reload stuff (changing the privileges directly via update / delete and the flush privileges is probably the best analogy). However, I could not find any versions of flush that would affect the stored procs based on the documentation. So, I do not think there is any way to make the deletion of the stored proc final in the current MySQL session.
The real danger with your direct deletion approach is that it relies on an undocumented feature of MySQL. This feature may change without any notice in a future version of MySQL, making an upgrade impossible. Also, without actually debugging MySQL itself, it is very difficult to say if your approach has any unintended side effects.
For these reasons, I would not recommend to use this approach in a production code. If it is a one-off exercise, then you may get away with it.
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.
In reading through the documentation, I noticed that MySQL's SELECT syntax has a clause that I had never really caught before:
SELECT
...
[PROCEDURE procedure_name(argument_list)]
...
I am intrigued, since from what little I could understand from their terse explanation and their example with PROCEDURE ANALYSE, one can pass data (and possibly metadata as well?) from a SELECT statement into a stored procedure. However, searching elsewhere for more details didn't yield any results, and the source for the ANALYSE procedure proved elusive to SHOW PROCEDURE calls in every database.
I ask more out of curiosity, since I know nothing about it, but what is this clause for, and what can I do with it?
Here is an explanation by
Morgan Tocker (MySQL Community Manager)
http://www.tocker.ca/2015/06/29/plan-to-deprecate-procedure-analyse.html
I'm working with MySQL 5.1.39 and Visual Studio 2008 and connecting both with MySQL Connector Net 6.1.2.
What I'd like to do is once a MySqlConnection object is created, be able to handle the "event raised" when a field in a specific row in a given table is updated.
I mean, when that value in that table has been manually changed or modified from any other application, I'd like to receive a signal in my opened VB.NET application. Until now, I do it from opened VB.NET application checking that table every X seconds, but I wonder if it could be done in a better way.
Many thanks for your attention and time.
Ideally, there is the SIGNAL construct, which you can use to field SQL logic errors, but that is not available until MySQL 5.5. It would be best to upgrade to 5.5, if at all possible.
EDIT: There isn't really a good solution for this before 5.5. The TRIGGER works for getting the updates, but not for sending them outside of the database. Be careful, though, as this doesn't work if you're updating through FOREIGN KEY actions, such as CASCADE or UPDATE, as TRIGGERs are not called for these actions. So watch out for that.
DELIMITER $$
CREATE TRIGGER my_trigger_name AFTER UPDATE ON my_table_name
FOR EACH ROW BEGIN
CALL my_on_update_procedure(NEW.entry_name, NEW.whatever_else)
END $$
DELIMITER ;
What my_on_update_procedure does is up to you. Your solution is probably the best bet for 5.1.39 (I would not recommend locking due to scalability issues), but 5.5 would give you the SIGNAL construct, which is exactly what you want (so upgrade!).
I never worked with that but I think "TRIGGER" could be what you're looking for.
http://dev.mysql.com/doc/refman/5.1/en/create-trigger.html
My first thought was to use a database trigger to trigger some sort of notification: message through email, MOM or anything else. Googling didn't turn much up though. I found one approach based on notification through locks: linky. Could be a sane approach...
Oh, and in that blog post they also talk about MySQL UDFs which lets you execute arbitary code when triggers fire. Apparently there is libs to various languages. There is also a duplicate question here on stackoverflow. Cheers