Validate Date at MySQL - mysql

How do you validate a date in MySQL ? In SQL Server, we have "ISDATE()" to validate whether the expression is a valid date. What function do we use in MySQL ?

Simply use date(your_date_here) and that will check if a date is valid.
EDIT:
If you really wanna have a isDate returning true or false, you can use this:
CREATE FUNCTION IsDate (sIn varchar(1024)) RETURNS INT
BEGIN
declare tp int;
if (select length(date(sIn)) is null )then
set tp = 0;
else
set tp = 1;
end if;
RETURN tp;
END
cheers

Try a solution like this one I used with Oracle to Sql Server move in SSIS. Dealing with Timestamp/Datetime when copying data from Oracle to SQL Server using SSIS
From your description, Oracle and MySql appear to handle dates similarly.

Related

MySQL Function Characteristic

I want to create a function that basically returns a random string. I don't know what characteristics to assign in this situation. I'm also in an environment that uses binary logging.
Here's a simplified version of my function:
CREATE FUNCTION `MYRAND`() RETURNS char(10) NOT DETERMINISTIC
RETURN CONCAT('rand_', FLOOR(RAND() * 10000));
I get this error when creating the function in my environment.
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in
its declaration and binary logging is enabled (you might want to use
the less safe log_bin_trust_function_creators variable)
Possible characteristics:
NOT DETERMINISTIC - used because this function returns random values
READS/MODIFIES SQL DATA - Function does not read data from tables
NO SQL - I am calling other SQL functions (RAND) so I'm not sure if I should be specifying this or not...
Any advice on how to properly define this function when binary logging is enabled would be appreciated.
MySQL wants you to declare the function as DETERMINISTIC, NO SQL, or READS SQL DATA.
Is it DETERMINISTIC? No - Since it is random.
Does id read SQL DATA? No - Since you have no SELECT statement.
Does it modify SQL DATA? No - Since you have no INSERT, UPDATE or DELETE statement.
Since your function does not touch any data in the DB it's NO SQL.
So you should declare it as NOT DETERMINISTIC and NO SQL
CREATE FUNCTION `MYRAND`() RETURNS char(10) NOT DETERMINISTIC NO SQL
RETURN CONCAT('rand_', FLOOR(RAND() * 10000));
Use somthing like this code:
CREATE FUNCTION get_string(in_strlen int) RETURNS VARCHAR(500) DETERMINISTIC
BEGIN
set #var:='';
while(in_strlen>0) do
set #var:=concat(#var,IFNULL(ELT(1+FLOOR(RAND() * 1000),1,2,3,4,5,6,7,8,9));
set in_strlen:=in_strlen-1;
end while;
RETURN #var;
END

illegal use of LONG datatype while copying Mysql table to Oracle

I have a MySQL and a Oracle server. I have to periodically copy some tables from MySQL to Oracle server and this is done via a scheduled PLSQL procedure and for this I have created a DBLINK between MySQL and Oracle. Everything is working fine until I had to copy one table which started giving error
Example
create table table_to_copy
as
select * from table_to_copy#DBLINK;
"oracle sql error ora-00997 illegal use of long datatype"
I have read couple of comments and this is mostly because of implicit conversion and most of the suggestions were to perform explicit to_lob conversion. But doing anything manual is not a feasible option.
Please note that
work arrangement is such I do not have any access to MySQL server the only thing I get is table name and have DBLINK. So I can only pull data using select statement
Solution for above mentioned issue has to be dealt in some kind of automated fix. This is because the request for table copy can be hundreds of table as any given point and I cannot go through all tables to fix/check manually.
Please help, your expert comments are highly valuable for me.
Note : there are some other questions here which might look similar like
Illegal use of LONG datatype Oracle
but they don't have the solution to what I am looking for.
I appreciate that this is rather late, and that I don't have this exact setup. However, what I have done from Oracle (11gR2) to SQL Server (2008R2 and earlier) is to read INFORMATION_SCHEMA.COLUMNS through the database link and then dynamically generate a string to EXECUTE IMMEDIATE in PL/SQL.
DECLARE
TYPE associative_array IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(50);
data_type_tranforms associative_array;
dynamicSQL varchar2(32767);
column_list varchar2(32767) := '';
expressions varchar2(32767) := '';
FUNCTION apply_transform(column_name VARCHAR2, data_type VARCHAR2) RETURN VARCHAR2 AS
transformed VARCHAR2(1000);
BEGIN
IF data_type_transforms.exists(data_type) THEN
transformed := replace(data_type_transforms(data_type),'$$',column_name);
ELSE
transformed := column_name;
END IF;
RETURN transformed;
END apply_transform;
FUNCTION strip_last_character(input VARCHAR2) RETURN VARCHAR2 AS
/* Remove the delimiter trailing after the last entry */
BEGIN
RETURN SUBSTR(input, 1, LENGTH(input) - 1);
END strip_last_character;
BEGIN
data_type_transforms('LONG') := 'to_lob($$)';
FOR col IN (
SELECT column_name
,data_type
FROM information_schema.columns#DBLINK
WHERE table_name = 'TABLE_TO_COPY'
ORDER BY ordinal_position
) LOOP
column_list := column_list || col.column_name ||',';
expressions := expressions || apply_transform(col.column_name, col.data_type) ||',';
END LOOP;
dynamicSQL := 'INSERT INTO table_to_copy ('||
strip_last_character(column_list)||
') SELECT '||
strip_last_character(expressions)||
' FROM table_to_copy#DBLINK';
EXECUTE IMMEDIATE dynamicSQL;
END;
I keep a series of templates in a PL/SQL index-by array, with the index being a data type and the value being an expression like 'to_date(''$$'',''YYYYMMDD'')' from which the characters $$ get replaced with the column_name. If you need to drop a data type entirely, which I often do, I just put an empty string in the data-type array.

Write a SQL function with that work based on the SQL Server version

We have clients that are running on SQL Server 2008 and 2012.
I want to write a function that is going to use Format function. I have a custom function that is doing almost same thing as Format in SQL Server 2008, but its performance is worse than Format.
I wanted to make it conditional so if it's running on SQL Server 2012, then it would use the built-in T-SQL Format and if it's on SQL Server 2008, then it use my own custom function.
So I wrote a function like this:
CREATE FUNCTION [system].[FunctionName1]
(
#param1 VARCHAR(MAX),
#param2 VARCHAR(MAX)
)
RETURNS nvarchar(Max)
AS
BEGIN
DECLARE #SQLVersion VARCHAR(16) = CONVERT(VARCHAR(16), SERVERPROPERTY('ProductVersion'))
SET #SQLVersion = LEFT(#SQLVersion, ISNULL(NULLIF(CHARINDEX('.', #SQLVersion, 1 + CHARINDEX('.', #SQLVersion)) - 1, - 1), 0))
DECLARE #Return DECIMAL(4, 2) = CASE
WHEN ISNUMERIC(#SQLVersion) = 1
THEN CONVERT(DECIMAL(4, 2), #SQLVersion)
ELSE 0
END
IF #Return > 11.0
BEGIN
RETURN Format(#param1, #param2)
END
ELSE
BEGIN
RETURN Format_Custom(#parm1, #param2)
END
RETURN NULL
END
The problem is in SQL Server 2008: the format function is unknown. So it throws a syntax error when I want to deploy it. I already have a work around for it with deployment script. But I want to know can I somehow with sql built-in functions pass the Format line or ignore it?
No, it can't be done in a function.
It has to be able to compile the code before any of your logic can execute, and it's failing at that point because there's a function it doesn't know of.
And you can't apply the usual work-around to get past the compilation error - putting the not-certain-to-compile code in as a string and compiling/executing it separately using an EXEC call - since you're not allowed dynamic SQL in UDFs.

Oracle equivalent for MySQL code "insert into dummy" to return error message

I have a couple of hundred triggers in mysql db which i'm migrating to Oracle db. There's an statement that i see a lot which i haven't been able to find an equivalent one in oracle.
INSERT INTO $some_kind_of_message._BD_TRIGG$ (dummy) VALUES (value);
i've seen this also in procedures and functions, and it seems to 'return' a message to the aplication who calls the procedure (i think). i'm kind of new in both RDBMS but i've been working with oracle a couple of months.
Is there an equivalent statement to replace the mysql's one in oracle ? Thanks a lot.
EDIT:
This is an example trigger of many. This one is used for login validation.
I'm not very sure about oracle's trigger syntax but that's not the problem now.
The 'case' part is still in mysql syntax. I havent been able to find information in mysql nor oracle documentation. It is not a normal insert, it is some kind of return message that mysql uses (thats what i guess) and i've seen it also in functions and procedures.
¿How can i replace it for oracle to perform the same task?
CREATE OR REPLACE TRIGGER adduser
BEFORE INSERT
ON tbl_users
FOR EACH ROW
DECLARE flag INTEGER;
begin
flag := 1;
/* validate login */
IF(LENGTH(TRIM(:NEW.login)) < 4) THEN
flag := -1;
END IF;
/* valido clave */
IF(flag = 1) THEN
IF(LENGTH(:NEW.clave) < 3) THEN
flag := -2;
END IF;
END IF;
CASE flag
WHEN -1 THEN INSERT INTO $login_less_then_4_characters._BD_TRIGG$ (dummy) VALUES ('error');
WHEN -2 THEN INSERT INTO $pass_less_then_5_characters._BD_TRIGG$ (dummy) VALUES ('error');
ELSE flag := 0;
END CASE;
END;
I think you need RAISE_APPLICATION_ERROR() function/procedure.
Syntax:
raise_application_error(error code, your error message);
Example:
raise_application_error(-20001, 'Login must have 4 characters or more');
In Oracle custom aplication error codes are between -20000 and -20999.
More information here:
Oracle PL/SQL - Raise User-Defined Exception With Custom SQLERRM
Oracle documentation: link
I'm not familiar with MySQL syntax but in Oracle it translates as
Insert into table_name(column_name) VALUES (value);
where dummy is a column in some table or parameter passed to function. You cannot use procedures, triggers in Insert statements in Oracle. You may use Function() in DML statements, e.g. SELECT your_function(dummy)..., INSERT your_function(dummy)... And function returns a value as we all know.

Does this function conform to ANSI SQL standard?

I was wondering if anyone can tell me if this function follows ANSI SQL standard, and for future reference are there any resources that i can use to find if my SQL conforms to ANSI standards. And the DBMS i am using is MySQL.
CREATE FUNCTION INCREMENT()
RETURNS INT
BEGIN
DECLARE oldVal INT;
DECLARE newVal INT;
SELECT currentVal INTO oldVal FROM atable FOR UPDATE;
SET newVal=oldVal +1;
UPDATE atable SET currentVal=newVal;
RETURN newVal;
END;
Found a validation tool that can check if your SQL conforms to SQL 2003.
http://developer.mimer.com/validator/parser200x/index.tml
Based on this comment
basically i need to retrieve the new updated value if i do UPDATE
table SET current = current + 1 and then perform a select to get the
new value, this could cause issues as what if another transaction
updates between the update and select.
I don't think your problem has anything at all to do with SQL standards. I think your problem has to do with transactions and with transaction isolation levels.