Postgres CASE statement not working in SQL Server - sql

I've written a query in postgres (on PGAdmin) and I'd like to put it in SSMS2012 for reporting purposes however it doesn't seem to allow the CASE statement, this is my query:
SELECT *
FROM OPENQUERY (POSTGRESQL,
'SELECT
Table1 AS Table_1,
CASE Table2
WHEN 75887 THEN ''1''
WHEN 75888 THEN ''2''
WHEN 75889 THEN ''3''
WHEN 75890 THEN ''4''
WHEN 75891 THEN ''5''
WHEN 75892 THEN ''6''
END AS Table_2,
DateTable1 AS DateTime
FROM SuperTable1 ')
And I'm getting the error:
OLE DB provider "MSDASQL" for linked server "POSTGRESQL" returned
message "Requested conversion is not supported.".
Msg 7341, Level 16, State 2, Line 1
Cannot get the current row value of column "[MSDASQL].table_2" from OLE DB provider "MSDASQL" for linked server "POSTGRESQL".
I've noticed if I remove the whole case statement it has no issues retreiving the data in the columns in the SELECT statement and the whole thing (including the CASE statement) works fine in PGAdmin.

Try simplify the query
Run 4 separated querys to determinate which one is giving you the problem.
Also try using 1 instead of ''1''
SELECT Table1 AS Table_1
SELECT DateTable1 AS DateTime
SELECT
CASE Table2
WHEN 75887 THEN 1
END AS Table_2
SELECT
CASE Table2
WHEN 75887 THEN ''1''
END AS Table_2

Related

Linked server errror: Cannot get the current row value of column

I have this query in SQL SERVER:
select *
from ADRESSEN
where Transferred is NOT null
and NR_ID not in (Select NR_ID from openquery(PROD, 'Select * from TABELLEN.NUMMERN'))
When I execute this query I get this error:
OLE DB provider "OraOLEDB.Oracle" for linked server "PROD" returned message "".
Msg 7341, Level 16, State 2, Line 12
Cannot get the current row value of column "[OraOLEDB.Oracle].NR_ID" from OLE DB provider "OraOLEDB.Oracle" for linked server "PROD".
But when I comment one of the condition in WHERE and I execute it, the query works:
select *
from ADRESSEN
where Transferred is NOT null
It works! And this too:
select *
from ADRESSEN
where
NR_ID not in (Select NR_ID from openquery(PROD, 'Select * from TABELLEN.NUMMERN'))

select from missing table error in subquery (after WHEN EXISTS in CASE)

** edited to invert logic in EXISTS test
I need to select a field from a table that may not exist. I also need to do this in a sub query.
There is a code release coming from engineering that will add a table to a database I scrape for reporting. If the table exists, select the field. If it does not, give a generic failure.
** Yes, there are tons of examples on how to use EXISTS. This goes outside of those as it deals with something that may not exist.
The new code release will rollout to several sites, some may not have the table immediately where others will. My stuff has to ready for Day Zero - aka: rolled out before hand (day -1?).
Here is my code (tables and columns renamed) that I am trying to make work in SQL Server Management Studio (SQL 2016) (SSMS 17.4)
select 'Cern' as SiteName,
(
select
case when exists (select 1 from sys.tables where name like 'ProtonAcceleratorSecurity')
then
(select top 1 isnull(SecurityID,'Not on file') from [ProtonAcceleratorSecurity] with (nolock) )
else
(select 'No Security Table Found')
end
as SecurityID
It looks contrived, but it is very near what I am trying to do, using that exact query (but nothing to do with security...)
The goal is to get back the site name, and the first security ID (at random - doesn't matter - no consistency required) - but only if the table actually exists.
The problem is that SSMS throws an error telling me that the table is an invalid object which I already know.
"Invalid object name 'ProtonAcceleratorSecurity' "
Final answer from #TabAlleman, with a minor correction:
SET #sql = '
select ''Cern'' as SiteName, ' +
( select
case when exists (select 1 from sys.tables where name like 'ProtonAcceleratorSecurity')
then
'(select top 1 isnull(SecurityID,''Not on file'') from [ProtonAcceleratorSecurity] with (nolock) )'
else
'''No Security Table Found'''
end )
+ ' as SecurityID ';
EXEC (#sql); ```
The reason for your error is that SQL Server will parse and compile your entire statement before it executes it. So your query cannot contain references to invalid objects, even though the query itself checks to make sure the object is valid before referencing it. The parser isn't smart enough to know that the subquery will not be called if the object doesn't exist, so it will prevent you from running the query at all.
One way you can trick the parser is through dynamic sql, which doesn't get pre-parsed:
DECLARE #sql varchar(max);
SET #sql = '
select ''Cern'' as SiteName, '
+
select
case when exists (select 1 from sys.tables where name like 'ProtonAcceleratorSecurity')
then
'(select top 1 isnull(SecurityID,''Not on file'') from [ProtonAcceleratorSecurity] with (nolock) )'
else
'''No Security Table Found'''
end
+
' as SecurityID
';
EXEC (#sql);
EDIT because I'm not testing as I go, but just to make the idea clear:
You need to check for the existence of the table in the outer query, but then only construct a dynamic query that uses the table if it exists. To make it really simple, ignoring your original CASE structure, you want to logically do this:
IF EXISTS({SELECT query to test for MyTable})
#SQL = 'query that references MyTable';
ELSE
#SQL = 'query that doesn't reference MyTable';
EXECUTE (#SQL);
PS: I think I just fixed the syntax in my first example.
I don't think there is any way to do this in a single query. One suggestion is to hide this in a view:
IF OBJECT_ID('ProtonAcceleratorSecurity') IS NULL
BEGIN
CREATE VIEW ProtonAcceleratorSecurity
SELECT 'Not on file' as SecurityID
END;
Then your query can work simply as:
select 'Cern' as SiteName,
(select top 1 coalesce(SecurityID, 'Not on file')
from ProtonAcceleratorSecurity
) as SecurityID
You are getting the problem because the table must exist when the statement is executed.
If you divide it into two statements then there is no problem. The one referencing the non existent table is marked for deferred compilation and as it is never executed the full compilation is never needed and no error.
IF OBJECT_ID('ProtonAcceleratorSecurity', 'U') IS NULL
SELECT 'Cern' AS SiteName,
'No Security Table Found' AS SecurityID
ELSE
SELECT TOP 1 'Cern' AS SiteName,
isnull(SecurityID, 'Not on file') AS SecurityID
FROM [ProtonAcceleratorSecurity] WITH (nolock)
ORDER BY ....

Insert return records from stored procedure - SQL

The script below return a select records:
EXEC [LINK_SERV].[DB_SAMPLE].[dbo].[SP_SAMPLE] '1235123'
The I want to insert the return records to a temp table so I wrote the script below (assumed temp table is already created):
INSERT INTO #TempTable
EXEC [LINK_SERV].[DB_SAMPLE].[dbo].[SP_SAMPLE] '1235123'
But I get this error:
OLE DB provider "SQLNCLI11" for linked server "LINK_SERV" returned message "The partner transaction manager has disabled its support for remote/network transactions.
Msg 7391, Level 16, State 2, Line 25
The operation could not be performed because OLE DB provider "SQLNCLI11" for linked server "LINK_SERV" was unable to begin a distributed transaction.
Please advise the specific config to enable this. I tried the same code in some other server and it work. Thank you in advance.
This is where the beauty of OPENQUERY() comes into great use.
i.e. something like this...
INSERT INTO dbo.MyTable2
SELECT Col1, Col2, etc
FROM dbo.MyTable1
LEFT JOIN OPENQUERY(<<LINKEDSERVER>>,
'SELECT BLAHBLAH
FROM dbo.BLAHBLAH WHERE <something> = <something>);

update error and rollback transaction

I have 3 tables ticket_addresses,tickets,['2014nosec add']. I want to update this ticket_addresses table but unfortunately i have run this query and it updated the entire table where the column ta_address_2 with '.'.
my doubt is my query is wrong because the from table ['2014nosec add'] is different from the update table and it does not have ta-address-2 column on it should give me an error because the from table is not the in the list.
is there any way to rollback the update query as i have not used it as transaction . I am using sql server managament studio.
update
ticket_addresses set ta_address_2 = '.'
FROM ['2014nosec add'] inner join tickets ------> I think this is wrong here.. it should be ticket_addresses table(right)
on ['2014nosec add'].[PCN] = tickets.t_reference
where ta_address_2 = ''
and ta_address_1 <> ' ' and t_camera_ticket = '-1'
and
convert (datetime,t_date_time_issued,101) between convert(datetime,'2014/04/15',101) and convert (datetime,'2014/06/06',101)
By default SQL Server using "Autocommit" mode for transaction management. So you can't rollback this query because it already commited.

Handling Dates from Oracle to SQL Server 2005 using OPENQUERY

I have linked SQL Server 2005 to an Oracle Server, and am using OpenQuery() to pass data from Oracle to SQL Server.
So, for instance, the following query works fine:
SELECT *
FROM OPENQUERY(ORACLE_LINK, 'SELECT FIELD1
FROM ORACLE.TABLE1');
Everything works, unless I ask for a field which is a date/time in the Oracle database. For instance, say that TABLE1 has ten fields, one of which is a timestamp. If I ask for all nine fields except for the timestamp, it works. If I ask:
SELECT *
FROM OPENQUERY(ORACLE_LINK, 'SELECT *
FROM ORACLE.TABLE1');
I get the following error:
OLE DB provider "MSDAORA" for linked server "ORACLE_LINK" returned message "Oracle error occurred, but error message could not be retrieved from Oracle.".
OLE DB provider "MSDAORA" for linked server "ORACLE_LINK" returned message "Data type is not supported.".
I also get the same error if I ask for only the timestamp field.
What is the best way of handling this error? Thanks.
I do it with this function (partial code):
select #StringOut = '{ts ''''' + convert(varchar(20), #DateIn, 20) + ''''' }';
RETURN #StringOut
and this goes into the query:
and procedure_date_dt = ' + dbo.TimestampString(#date) + '
and event_type = ''''Time Notation''''
and it works when I run it.