selecting from nothing in Oracle SQL happens while referencing the dual table, like
SELECT sysdate FROM dual;
Now I'd like to have a query that also works for PostgreSQL, but selecting from dual there isn't possible. I know that I can drop the whole FROM part, but then it won't work in Oracle.
I've also tried things like SELECT CURRENT_TIMESTAMP FROM VALUES(1)) V(C);, but Oracle can't do this, either.
So is there a way to select from nowhere without using the dual table in Oracle SQL?
Alternatively, create a table named dual in Postgres, made of 1 row and 1 column
create table dual as (select 1);
and you can use it in Postgres as you would in Oracle
select 'whatever' from dual;
?column?
-----------
whatever
sysdate in Oracle is a built-in function, i.e. not a database table column. You can use any table as long as the query returns precisely one row, e.g.
select sysdate from EMP where rownum < 2
If you have a small table, TABLE_B, with at least one row, you could try selecting a single row from it.
select sysdate from TABLE_B where rownum < 2;
The contents of the table don't matter because you won't be selecting any of its columns.
The below code generates a fake row in both Oracle and Postgres (10+), using the XMLTABLE function. This code is pretty weird but it doesn't require any custom objects.
--Generate a fake row in either Oracle or Postgres.
select *
from xmltable
(
--The expression syntax is different for Oracle and Postgres.
--Oracle can use a literal, Postgres must reference the XML.
--The string '' is null in Oracle but not null in Postgres.
case when '' is null then '1' else '/a' end passing '<a>1</a>'
columns test int path '.'
);
test
----
1
Related
DUAL is a system table that is used to get constants and results of system functions.
However it only has one column named "dummy" and only a row with X value in it so this doesnt work:
My question is, is there a system table that can pull this trick off? A (single-column) table that returns a row regardless of how its one column is queried, with the value in the where clause.
What you want to do violates how SQL works. However, if you always wnat to return exactly one row from a "table", you can use aggregation with no group by:
select max(dummy)
from dual
where dummy = '5'
The returns value is NULL.
Perhaps it would be easier to suggest something if you explained what problem you are trying to solve.
As you asked:
A (single-column) table that returns a row regardless of how its one column is queried, with the value in the where clause.
SQL> select dummy from dual where dummy = '5' or 1 = 1;
D
-
X
SQL>
dual is a (single-column) table
this query returned a row
value ('5') is in its where clause
I presume that "regardless of how its one column is queried" is also satisfied
Why "where clause"?
SELECT '5' AS dummy FROM dual
DUMMY|
-----|
5 |
I'm trying to create a select statement that returns one row (date) combining 3 column entries
My idea that doesn't work:
SELECT
TO_DATE( d_date.day_varchar +
d_date.month_varchar +
d_date.year_varchar , 'DD/MM/YYYY')
FROM d_date
Is this possible in Oracle SQL and how can I get this result?
In SQL Server there is a DATEFROMPARTS() function but I don't know that well Oracle specifics ...
Your approach seems fine. You just need to update it for Oracle syntax:
select to_date(d_date.year_varchar || d_date.month_varchar || d_date.day_varchar, 'YYYYMMDD')
It is a curious that you would have a table with date parts, but not the actual dates.
I have this query as a part of powershell script and it runs ok on Sql server but fails on Oracle
select case when OBJECT_ID (N'INTERFACE_DEFINITION', N'U') is null then 0 else 1 end
Here is error: ORA-00923: FROM keyword not found where expected
Is there some change required to make this work?
Thanks.
select case when 'a' > 'b' then 0 else 1 end
from DUAL;
The DUAL table is present in every Oracle database. This special table
contains just one column. The column is named DUMMY, and it has a
datatype of VARCHAR2(1). The DUAL table contains only one row. That
row has a value in DUMMY of ‘X’.
The purpose of DUAL is simple—to have
something to run a SELECT statement against when you don’t wish to
retrieve any data in particular but instead simply wish to run a
SELECT statement to get some other task accomplished.
Verifying that an object exists:
OBJECT_ID (N'INTERFACE_DEFINITION', N'U')
In Oracle you may use this query:
select count(*) from all_objects where object_name = 'INTERFACE_DEFINITION';
all_objects doesn't necessarily shows you all the objects in the database. It only shows you the objects on which a current user has any priviledges.
I need a common select statement that returns a fixed value / row without the need of tables, which has to work with both Oracle & Sql Server.
eg for Oracle I know I can use:
select 'O' AS INDICATOR from DUAL;
But this won't work on Sql Server.
Can this be done with the same SQL on both Oracle & SQL Server?
AFAIK, you'll need different queries, unless you can find a table that exists both on the SQL Server and on the Oracle Server.
Oracle uses the DUAL table for dummy queries, while the syntax to just select a constant on SQL server is a bit simpler:
select 'O' as Indicator
will return a one-row recordset.
P.S. If you intend to write just standard SQL and have it work on both SQL Server and Oracle, note that there are lots and lots of differences, even if you do not use database-side code (stored procedures and functions).
Off the top of my head, some things that are different:
Case statement syntax
NVL vs IsNull
Null sorting behaviour
Data conversion functions
String manipulation functions
etc, etc.
You can't select data in Oracle without from statement. So you need to have a table in Oracle (common practice is to use standard table - Dual). The best solution if you really need to run same query on both database servers is to create Dual table with only one row in MS SQL. But really it's better to use different queries for different servers (maybe via some abstraction layer).
Use a common table expression (CTE) e.g.
WITH D (INDICATOR)
AS
(
SELECT *
FROM (
VALUES ('O')
) T (c1)
)
SELECT INDICATOR
FROM D;
Or more simply in line:
SELECT *
FROM (
VALUES ('O')
) D (INDICATOR)
You can create the DUAL table in SQL Server:
CREATE TABLE DUAL (DUMMY NVARCHAR(1) NOT NULL);
INSERT INTO DUAL VALUES ('X');
and then use the same query as in Oracle:
select 'O' AS INDICATOR from DUAL;
Here's the structure of a query I came across:
MERGE INTO TABLE t
USING (SELECT ? id, ? email, ? cr_date, ? info, ? status FROM dual) n
ON t.id=n.id and t.email=n.email
WHEN MATCHED THEN UPDATE SET z.info = n.info z.status='Y'
WHEN NOT MATCHED THEN INSERT (info, status) VALUES (n.info, n.status)
I've read up on using DUAL to return SYSDATE or other operations... is the SELECT simply returning some input values into a table (row) to simplify further operations in the other clauses?
Thanks!
The code you came across is meant to update a single row, or create it if it doesn't exist.
DUAL is a special system table containing just one row.
Selecting from DUAL is a workaround for Oracles inability to do simply:
select sysdate;
Note that it doesn't have to be dual, it can be any one-row-table or even a query that returns one row.
select sysdate
from dual;
is equivalent to:
select sysdate
from my_one_row_table;
and
select sysdate
from my_table
where my_primary_key = 1;
Since version 10g, the dual table has a special access path which shows up in the execution plan as "fast dual", which results in 0 consistent gets, which isn't possible to achive on your own using other tables.
a) Yes you can use like this statement. But you must rename your "date" field name cause its keyword of oracle.
b) but i stongly recommend to create procedure for this.
Read about DUAL table : http://www.orafaq.com/wiki/Dual
It commonly used for SYSDATE, Can be used for multiple fields such as below too:
SELECT USER, sysdate from dual;
The statement appears to be doing essentially an Update Else Insert using a little trick with DUAL. The "?" appear to be bind variables.
The same logic could look like (in pseudocode):
UPDATE t
SET t.id= ?,
t.email= ?,
t.status= 'Y'
IF update updated 0 rows THEN
INSERT into t
VALUES (?, ?)
where the two ? are the "info" and "status" variables respectively.
Using DUAL just reduces your work into one database call instead of two.