Oracle WITH clause returns no data - sql

I am trying to use a WITH clause in Oracle, but it is not returning any data.
This is the query I am trying to run...
with test as
(select count(*)
from my_table)
select *
from test;
When I run this code, I get back the count of the records in my_table
select count(*)
from my_table
I am on Oracle 10g so the query should work...
select * from v$version;
yields
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Solaris: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
Could it a permissions issue or something?
*EDIT: *
I believe my question is clear. Using the WITH statement will not return any records for me, even though the "select count(*) from my_table" statement inside the WITH statement works correctly, which would lead me to believe that there is another issue that I am unable to figure out, hence this question :)
EDIT 2
OK, so if I try and execute the query from a linked server from SQL server management studio I get some error information back:
sg 7357, Level 16, State 2, Line 1
Cannot process the object "with test as
(select count(*)
from v$version)
select * from test;". The OLE DB provider "MSDAORA" for linked server "MyServer" indicates that either the object has no columns or the current user does not have permissions on that object.

Maybe the optimizer is materializing the count query (dumb, I agree). It's a shot in the dark but do you have these privileges?
grant query rewrite to youruser;
grant create materialized view to youruser;

Try giving the aggregate an alias name.
with test as
(select count(*) as MyCount
from my_table)
select MyCount
from test;

The following worked just fine for me (10gR2)
SQL> with test as
2 (select count(*)
3 from user_tables)
4 select *
5 from test;
COUNT(*)
----------
593
SQL>
What client are you using?

This question is confusing. Are you saying you are or are not getting back the count from my_table?
You should be getting back the count because that's exactly what you asked for in the with clause.
It's analogous to writing:
select *
from (select count(*) from my_table);

Some people at my company ran into this the other day - we traced it down to the Oracle client version [and thus the OCI.dll] version that was being picked up by PL/SQL developer. Some of our dev PCs had Oracle 8 (!) client installs still knocking around on them as well as more recent versions.
The symptom was that not only were queries written using a WITH clause returning no rows, they were returning no columns either! If you manually set the app to pick up the Oracle 11 oci.dll then it all worked.
I think what is going on is that Oracle 8 predates the WITH clause (introduced in Oracle 9, and enhanced subsequently). Now, mostly you can get different versions of the Oracle client and server to talk to one another. However because the client has a certain amount of 'intelligence', it is supposed to be semi-aware of what sort of operation it is submitting to the database, and so does some form of primitive parse of the SQL. As it doesn't recognize the command as a SELECT, it treats it as some unknown command [e.g. possibly a DDL command] and doesn't recognize it as returning a resultset. If you turn on SQL_TRACE for the session you can see the SQL gets PARSEd and EXECUTEd fine on the server, but that no calls to FETCH are made.
I had a similar thing myself recently when trying to use the new WITH syntax in Oracle 12 that allows an inline function definition. If you try simple examples using an Oracle 11 thick client-based application, such as PL/SQL developer or SQL*Plus, then you get an error. If you use an Oracle 12 client, or a thin-client application that doesn't rely a client-side install, then it works.

Related

Standard SQL command to get current RDBMS

Is there any standard sql command that can show you the current RDBMS and version?
The reason for this question is that I am using a CMS remotely that use a SQL database, but I don't know which RDBMS is being used, so I thought maybe there is standard SQL command to print it, something similar to SQL server's ##version
This is not a direct answer to the question, but since there is no standard sql query or function to show the RDBMS, I will post the queries/functions/vars used to identify it.
-- SQL SERVER
SELECT ##version;
-- Postgres, mysql, mariadb
SELECT version();
-- Oracle
SELECT * FROM v$version;
-- sqlite
select sqlite_version();
Please pay attention that Mysql and Sqlite will show only the version and will not include engine name in contrast to other RDBMS.

sql server - Openquery vs 4part name

A view that references a remote server
4part name ([ServerName], [DatabaseName], [Owner], [Object Name]
OpenQuery
Which is better performance?
Why is performance good?
AFAIK, it depends a lot on your remote server type.
With recent SQL version (2016) on both server (local and remote), I didn't noticed any difference.
If your remote server is anything else (postgres, mysql...) your really should use OpenQuery as it executes the query on the remote server, getting only the correct resultset. If you use the 4 part name, SQL server will order and filter on local.
For example, take a 4 million record table and execute a query like :
SELECT * FROM reoteserver.database.schema.table where id = 4
With openquery, sql server will get only the record with id 4. Without, it will get all the table, and then filter it to get the id 4.
Late to the party here, but the difference essentially is that 4 part queries are executed locally, thus cannot utilise indexes or keys since the local server doesn't know about them. Instead it essentially retrieves the entire object, then applies the filter. On a small table, you would be unlikely to notice a difference, but on a table with millions of rows, you'd notice a difference. Openquery essentially tells the remote server to execute the query on it's behalf then pass the result back.
General rule I would say is;
NEVER join on to a table using 4 part. Only join using Openquery and I would even avoid that where possible, but that's more of a personal preference.
However, 4 part SP execution i.e. EXEC ServerName.DBName.SchemaName.ObjectName is essentially the same since that also tells the remote server to execute the query on its behalf.

Oracle - query failed statements

Is there a view (or other method) in Oracle, from which I can extract the failed sql statements, which were executed by the user? I tried to check v$sql but, as it turned out, it contains only the successful ones. I'm using Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production.
Thank You.
Blaim me if I'm wrong but as far as I understand sql gets logged on shared pool check and statements Laszlo mentioned select nonexistingcolumn from dual; failed on semantic check. My answer is you won't find invalid statements in DB.
https://docs.oracle.com/database/121/TGSQL/tgsql_sqlproc.htm#TGSQL178

Problem with select statement via a linked server

I am using MS SQL Server 2000 and have a link from a test db to a live db which is in replication. The link seems to work fine and I can select from any of the tables using any of the fields apart from the field with the constraints on creating ids. So if I run
select * from person where firstname like 'john' this works fine, but then if I run select * from person where id =1 then I get no data returned and I get no errors but the record exists.
Any advise is much appreciated.
Thanks
If select * from person where id =1 returns no rows then the record doesn't exist.
It's been a few years since I've worked with linked servers, but have you tried running profiler against the linked server (the live DB) to see that it's receiving the select statement and that it's receiving it correctly?
Can you see the record in enterprise manager through the dblink, or are you looking at the linked db directly?
Maybe your link is not pointing where you think it is.

SqlServer 2000 compatibility

The developer environment db server is SqlServer 2005 (developer edition)
Is there any way to make sure my SQL Queries will run in SqlServer 2000?
This database is set to Compatibility level "SQL Server 2000 (80)" but some queries that run without problems in the development system can not run in the Test Server (SqlServer).
(The problems seems to be in subqueries)
Compatibility levels are designed to work the opposite way - to allow an older version of T-SQL code to work without modifications on a newer version of SQL Server. The changes typically involve T-SQL syntax and reserved words, and it's possible to use SQL Server 2005 features such as INCLUDED columns in indexes on a database in Compatibility Level 80. However, you can't use 2005 T-SQL features such as CROSS APPLY.
Your best option is to develop/test all your code against a SQL Server 2000 instance. Note that you can use 2005's Management Studio to connect to the SQL Server 2000 instance, so you don't have to go backwards with regards to tools.
Problem solved:
In correlated subqueries you have to (in SQL2000) explicitly define the external field.
SQL2005:
SELECT * FROM Loans WHERE EXISTS (SELECT * FROM Collaterals WHERE COLLATERAL_LOAN=LOAN_NUMBER)
SQL2000:
SELECT * FROM Loans WHERE EXISTS (SELECT * FROM Collaterals WHERE COLLATERAL_LOAN=Loans.LOAN_NUMBER)
You should always explicitly define all fields, otherwise you will not get an error when you make a mistake and write
SELECT * FROM Loans WHERE EXISTS (SELECT * FROM Collaterals WHERE LOAN_NUMBER=Loans.LOAN_NUMBER)
If Collaterals-table doesn't have column LOAN_NUMBER, the Loans-table is used instead.