How to return today's date to a variable in Oracle - sql

I want to do this:
DECLARE #today as smalldatetime
SELECT #today = GetDate()
But i need an oracle translation

Oracle uses SYSDATE, and there's the ANSI standard CURRENT_TIMESTAMP (supported by both SQL Server and Oracle, besides others) to get the current date & time.
v_today DATE;
SELECT SYSDATE
INTO v_today
FROM DUAL;
...would be the equivalent to the TSQL you posted. Oracle uses the INTO clause for populating variables, where the variable data type must match the column position in the SELECT clause.

While not a strict translation, I prefer the following construction in Oracle:
v_today date; -- needs to go where variables are declared
v_today := sysdate; -- used where code is run.
Or even:
v_today date := sysdate;

Related

Save value into a variable in oracle db

I have a query where i have to use the result of it multiple times. So instead of running the query multiple times i want to save the query value into a variable once and use it multiple times to accelerate the query speed.
for example:
Declare VAr = select M_DATE from TBT
If you want to do this in an interactive client, the answer depends on the client. For SQLPlus you could do this:
VARIABLE my_date VARCHAR2(10);
BEGIN
SELECT to_char(sysdate, 'YYYY-MM-DD' ) INTO :my_date FROM dual;
END;
/
PRINT my_date;
SELECT * FROM my_table WHERE date_column = TO_DATE( :my_date, 'YYYY-MM-DD' );
Note that SQLPlus does not support a DATE type for its variables, so you need to convert to a string when storing then back to a date when using the value. I recommend always using an explicit conversion and format string, simply to avoid unexpected results if the default format is not what you are expecting.
Within a PL/SQL block or procedure, it would be a little simpler:
DECLARE
l_mydate DATE;
BEGIN
SELECT sysdate INTO l_mydate FROM dual;
SELECT whatever INTO l_whatever FROM my_table
WHERE date_column = l_mydate;
<etc...>
END;
/
If you want to store the result of the query then you need to use a select ... into;
var v_storedate VARCHAR2(19);
exec select m_date into :v_storedate from tbt;
print v_storedate;
For an anonymous SQL block
begin
select m_date
into :v_storedate
from tbt;
end;
/

Wrong date format for input parameter?

CREATE OR REPLACE PROCEDURE PROC1(
V_STARTTIME IN DATE,
V_ENDTIME IN DATE)
BEGIN
INSERT INTO TAB1
SELECT COINS FROM TAB2
WHERE DATE BETWEEN TO_DATE(V_STARTTIME,'MM/DD/YYYY') AND TO_DATE(V_ENDTIME,'MM/DD/YYYY');
COMMIT;
END;
SAMPLE DATE in Tab2 IS TIMESTAMP DATATYPE 5/5/2014 9:46:38.000000 AM
When I try to execute
Execute PROC1(TO_DATE('5/5/2014','MM/DD/YYYY'),TO_DATE('5/6/2014','MM/DD/YYYY'));
the procedure is successfully completed but my Insert into was ignored.
I tried printing the input date through dbms_output.put_line and the date did not return.
This is very, very similar to the question you asked yesterday.
If v_starttime and v_endtime are of type date, it makes no sense to call to_date on them. to_date does not take an argument of type date. It takes a parameter of type varchar2. If you try to pass a date to to_date, Oracle has to implicitly cast the date to a varchar2 using the session's NLS_DATE_FORMAT. If that doesn't match the format mask you're passing to to_date, you may get an error or you may get an incorrect result. As in yesterday's question, you want to avoid implicit conversions.
A date in Oracle has both a day and a time component (to the second). If you are doing the to_date in order to ensure that the time component is midnight, use the trunc function instead.
INSERT INTO TAB1( column_name )
SELECT COINS
FROM TAB2
WHERE <<timestamp column>> BETWEEN trunc( v_starttime ) AND trunc( v_endtime );
You say that your "insert was ignored". That seems highly unlikely. It's much more likely that your SELECT statement returned 0 rows so your INSERT inserted 0 rows. That's not an error. If you want to treat it as an error, you'd need to check SQL%ROWCOUNT after the INSERT and throw an error if the INSERT statement inserts 0 rows.
If the SELECT was not selecting any rows because of an implicit conversion error, then getting rid of the to_date and potentially adding the trunc would fix the problem.
The function TO_DATE requires string as first parameter.
CREATE OR REPLACE PROCEDURE PROC1(
V_STARTTIME IN DATE,
V_ENDTIME IN DATE)
BEGIN
INSERT INTO TAB1
SELECT COINS FROM TAB2 WHERE DATE BETWEEN V_STARTTIME AND V_ENDTIME;
COMMIT; --You should not use commit in procedure.
END;

How to store query result in a variable in sql

I am using following query:
DECLARE
result varchar2(100);
BEGIN
select (systimestamp - (select date_time from test where id=2945134)) into result from dual;
SELECT SUBSTR(result, 3,1) Final_result
FROM DUAL;
END;
It is showing an error like:
PLS-00428: an INTO clause is expected in this SELECT statement
06550. 00000 - "line %s, column %s:\n%s"
Cause: Usually a PL/SQL compilation error.
I need to store result value from first query into result variable and then use that result variable to show the substring (3,1) as a Final_result.
DECLARE
result varchar2(100);
BEGIN
select substr((systimestamp - (select date_time from test where id=2945134)), 3,1)
into result
from dual;
dbms_output.put_line(result);
END;
/
But this is a highly dubious thing you are doing. You are relying on implicit datatype conversion (interval --> varchar) which will not work properly if your NLS settings change.
You would better use to_char() to format the resulting interval to something appropriate.
Instead of making 2 select from the same table, just 1 should suffice.
Also as a practice, always try using the fully qualified name of your objects
Why do you need the "DUAL" table
DECLARE
#final_result varchar2(100);
BEGIN
select #final_result= SUBSTR((systimestamp - (select date_time from test where id=2945134)),3,1);
END;

Oracle Procedure error (PLS-00428)

This is the error message: PLS-00428: an INTO clause is expected in this SELECT statement. Meanwhile, this is the procedure for testing displaying the system date:
CREATE OR REPLACE
PROCEDURE "TEST_PROCEDURE"
AS
BEGIN
SELECT SYSDATE FROM DUAL;
END;
In the first place I don't need to use that INTO Oracle is insisting for me to do. Is there other way around beside using a cursor (I've seen it here https://stackoverflow.com/a/6029963/1983024)? I think it should not be like that, this does run normally just like in MS SQL without using INTO or cursor.
In the first place I don't need to use that INTO Oracle is insisting
for me to do.
The fact is, Oracle is correct: you do need to use an INTO to take the return value.
After all, if you want to display the result of the query you're going to need a variable to put it in first.
you can write
CREATE OR REPLACE
PROCEDURE "TEST_PROCEDURE"
AS
BEGIN
for r_row in ( SELECT SYSDATE s FROM DUAL)
dbms_output.put_line(r_row.s);
end loop;
END;
or you have to have a variable.
CREATE OR REPLACE
PROCEDURE "TEST_PROCEDURE"
AS
v_Date date;
BEGIN
SELECT SYSDATE into v_date FROM DUAL;
dbms_output.put_line(v_date );
END;
output format is dictated by your NLS_DATE_FORMAT setting, or you can be explicit like to_char(v_date, 'dd-mm-yyyy') etc.
Finally found a solution to the output I want (based on your responses) :D
CREATE OR REPLACE
PROCEDURE "TEST_PROCEDURE"
RET_DATE CHAR(10);
BEGIN
SELECT TO_CHAR(SYSDATE, 'MM/DD/YYYY') INTO RET_DATE FROM DUAL;
DBMS_OUTPUT.PUT_LINE(RET_DATE);
END;
This displays the SYSDATE with format of MM/DD/YYYY. Still, thanks for the replies and ideas (mostly #Jeffrey Kemp). Oracle just lengthens what MS SQL can normally do in one line :D
You can use like
CREATE OR replace PROCEDURE Test_procedure
IS
date CHAR(10);
BEGIN
SELECT To_char(SYSDATE, 'MM/DD/YYYY')
INTO date
FROM dual;
dbms_output.Put_line(date);
END;
it will return date into char format.
If you want to get date into date format just declare the date type variable then assign the sysdate value INTO that variable.Then use DBMS_OUTPUT.PUT_LINE(variable) to print the DATE.
If you wanted to do it in one line, you could also use:
CREATE OR replace PROCEDURE Test_procedure
IS
BEGIN
dbms_output.put_line(to_char(sysdate, 'MM/DD/YY'));
END;

Oracle SYSDATE question for datetime column ORA 12899

I wrote a trigger in which I have a line:
SELECT *
INTO :NEW.EVENTDATE
FROM (SELECT SYSDATE
FROM DUAL);
For some reason this does not work (EVENTDATE column has timestamp(0) type).
When I try to insert something I get error message saying that value is too long for that column. I though SYSDATE and timestamp(0) would coalesce and understand each other.
What the ?
You should just do this in PL/SQL
:new.EventDate := SYSTIMESTAMP;
but if you want to use SQL
SELECT systimestamp
INTO :new.EventDate
FROM dual;
Try an explicit cast such as
select cast(sysdate as timestamp(0)) from dual
As a thought, is there anything exotic with your session's calendar settings which might force a unusual conversion. If so, try specifying the appropriate calendar in a conversion.
select to_char(sysdate,'DD-fmMonth-YYYY','nls_calendar=''Arabic Hijrah''') from dual;
I don't know why this wouldn't work. Can you post the actual error (with code and everything) that you are getting?
I also don't know why you wouldn't just assign the variable:
:NEW.EVENTDATE := systimestamp;
What version are you running?
The following works fine on Oracle 11R2:
drop table tq84_eventdate;
create table tq84_eventdate (
data varchar2(10),
eventdate timestamp(0)
);
create trigger tq84_eventdate_trg
before insert on tq84_eventdate
for each row
begin
SELECT * INTO :NEW.EVENTDATE FROM (SELECT SYSDATE FROM DUAL);
end tq84_eventdate_trg;
/
insert into tq84_eventdate (data) values ('test');
select * from tq84_eventdate;
However, if I do a
insert into tq84_eventdate (data) values ('value too large!');
I get the ORA-12899 you mentioned. So, the error is probably not related to the select statement you posted, but to the data that you actually try to insert.
Also, on a related note, you can assign sysdate directly in the trigger, that is without the indirection of a select statement:
create trigger tq84_eventdate_trg
before insert on tq84_eventdate
for each row
begin
:new.eventdate := sysdate;
end tq84_eventdate_trg;
/
I was able to exhort my bosses to convert one column's type to another. Namely timestamp to DATE.
Strangely enough nobody throughout this branch has not pointed out that I could substitute Timestamp field with DATE field.