No rows returned when calling stored procedure although running code in that very SP returns rows - sql

Whenever I call a stored procedure that contains more than a single select statement I get no rows in the resultset although running the same code outside the SP returns the expected result. This has started happening by the time a database backup from a production environment was installed on the development server.
The example below returns no rows when run in Enterprise Manager 2008:
exec dbo.USP_S_CustomerLimit '00000053-0000-1148-5300-000000000000'
If I however execute all the code in that procedure by itself (like select it and press "run") I get the expected amount of result rows:
SELECT * FROM CustomerLimit WHERE Department =
(SELECT Department FROM Customer WHERE CustomerID = CONVERT(BINARY(16), CONVERT(UNIQUEIDENTIFIER, '00000053-0000-1148-5300-000000000000')))
I have also tried this variant of the code which unfortunately behaves in exactly the same way:
SELECT CustomerLimit.* FROM CustomerLimit
JOIN Customer ON Customer.Department = CustomerLimit.Department
WHERE Customer.CustomerID = CONVERT(BINARY(16), CONVERT(UNIQUEIDENTIFIER, '00000053-0000-1148-5300-000000000000'))
I feel it's some sort of right issue but I don't know where to check. I am db_owner on the server and I also belong to a group that is db_owner in the database in question. What could be the cause of this problem? If I create a testprocedure with just one select, f.e Select * from Customer then I get the correct result when executing that procedure but if I write f.e Select * from Customer where CustomerID in (select CustomerID from Customer) then I get no rows.. :(

Check whether you have rights/permission on all these three tables. Check the sys.objects for the listing of these tables.

Related

Can you force SQL Server to send the WHERE clause to Linked Server?

I'm trying to determine if a table in my SQL Server 2012 database has any records that don't exist in a table that's on a linked Oracle 11g database.
I tried to do this with the following:
select 1
from my_order_table ord
where not exists (select 1
from LINK_ORA..[SCHEMA1].[ORDERS]
where doc_id = ord.document_id)
and document_id = 'N2324JKL3511'
The issue is that it never completes because the ORDERS table on the linked server has about 100 million rows and as per the explain plan on SQL Server, it is trying to pull back the entire ORDERS table from the linked server and then apply the WHERE clause.
As per the explain plan, it views the remote table as having an estimated 10000 rows - I assume that's some kind of default if it is unable to get statistics..?
Even running something as simple as this:
select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511'
causes SQL Server to not send the WHERE clause and the query never completes.
I tried to use OPENQUERY however it won't let me add the doc_id to concatenate into the WHERE clause of the query string.
Then I tried to build a select FROM OPENQUERY string in a function but I can't use sp_executesql in a function to run it.
Any help is greatly appreciated.
I think this would logically work for you, but it may take too long as well.
SELECT sql_ord.*
FROM my_order_table sql_ord
LEFT JOIN LINK_ORA..[SCHEMA1].[ORDERS] ora_ord ON sql_ord.document_id = ora_ord.doc_id
WHERE sql_ord.document_id = 'N2324JKL3511'
AND ora_ord.doc_id IS NULL
Since you have problem with something as simple as select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511' have you try to create a table on the remote server that will hold the doc_id that you want to look at. So your SELECT will include a table that contain only 1 row. I'm just not sure about the INSERT since I can't test it for now. I'm assuming that everything will be done on the remote server.
So something like :
CREATE TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id (
doc_id nvarchar(12));
INSERT INTO LINK_ORA..[SCHEMA1].linked_server_doc_id (doc_id)
SELECT doc_id
FROM LINK_ORA..[SCHEMA1].[ORDERS] WHERE doc_id = 'N2324JKL3511';
select 1
from my_order_table ord
where not exists (select 1
from LINK_ORA..[SCHEMA1].[linked_server_doc_id]
where doc_id = ord.document_id)
and document_id = 'N2324JKL3511';
DROP TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id

SQL FileTable GetFileNamespacePath

I am using Filetable in SQL 2016. let's take a look at some select commands below:
1.
Select [stream_id] from <FileTable>
2.
Select [stream_id], [name] from <FileTable> with (nolock)
3.
Select [Stream_id], [name], file_stream.GetFileNamespacePath(0) as ntfsPath from <FileTable> with (nolock)
I must use with(nolock). if some one has opened a file such as a word document and I don't use 'NOLOCK', SQL returns only some records and then caught in a specific record and wouldn't return any records afterward. However number 1 and 2 return result but number 3 does not because of file_stream.GetFileNamespacePath(0). If I omit file_stream.GetFileNamespacePath(0) then SQL returns a result. Whats the problem with GetFileNamespacePath()?
Do I missed something in filestream configuration or use of Select command ?

SQL SELECT statement skips rows based on WHERE statement

I apologize, this may be a stupid question! I have created a procedure that maintains, and runs a series of procedures/functions. If error occurs on any procedure an email is sent to me, and an automatic refresh parameter is set with procedure name that failed. Single table houses all procedures (exact names as varchar2) to run in top-down order with looping structure. How can I skip to procedure that has failed with select statement along with grabbing all other procedures underneath procedure that has failed? Basically I would like the procedure to start where it has stopped, and continue the process of running all other procedures. I will appreciate any idea, because I am just learning.
UPDATE
For those confused. I need a SELECT statement that skips rows based on a where and grabs all other rows underneath first row. Basic psuedocode below ...
SELECT procedure_name
FROM table_whatever
SKIP ROWS that procedure_status <> 'completed'
AND grab all rows underneath
WHILST keeping rows in proper order
id procedure status
15 table_insert failed
16 table_update In Queue
17 email_completion In Queue
I need to grab failed procedure along with everything underneath.
Any ideas?
Thank you in advance!
I'll bite, what the heck. Based on your data above which assumes there can be only one row with a status of 'failed', and assumes procedures are in 'id' order:
SELECT procedure
FROM table_whatever
WHERE id >= (SELECT ID
FROM table_whatever
where status = 'failed')
ORDER by id;
Based on your minimal pseudocode, and assuming the 'proper order' is by ID, you can just exclude those that are completed:
SELECT procedure_name
FROM table_whatever
WHERE procedure_status <> 'completed'
ORDER BY id;
If you explicitly want to look for 'failed' - or so the same query can be used to kick off the sequence before anything has run - you could use an analytic query and inline view, so you only have to hit the table once:
SELECT procedure_name
FROM (
SELECT id, procedure_name, procedure_status,
MIN(CASE WHEN procedure_status = 'failed' THEN id END) OVER () AS failed_id
FROM table_whatever
)
WHERE id >= COALESCE(failed_id, 0)
ORDER BY id;
For a small table hitting it twice probably isn't too big a deal, so Gary_W's subquery approach would work just as well...

Selecting a sequence NEXTVAL for multiple rows

I am building a SQL Server job to pull data from SQL Server into an Oracle database through a linked server. The table I need to populate has a sequence for the name ID, which is my primary key. I'm having trouble figuring out a way to do this simply, without some lengthy code. Here's what I have so far for the SELECT portion (some actual names obfuscated):
SELECT (SELECT NEXTVAL FROM OPENQUERY(MYSERVER,
'SELECT ORCL.NAME_SEQNO.NEXTVAL FROM DUAL')),
psn.BirthDate, psn.FirstName,
psn.MiddleName, psn.LastName, c.REGION_CODE
FROM Person psn
LEFT JOIN MYSERVER..ORCL.COUNTRY c ON c.COUNTRY_CODE = psn.Country
MYSERVER is the linked Oracle server, ORCL is obviously the schema. Person is a local table on the SQL Server database where the query is being executed.
When I run this query, I get the same exact value for all records for the NEXTVAL. What I need is for it to generate a new value for each returned record.
I found this similar question, with its answers, but am unsure how to apply it to my case (if even possible): Query several NEXTVAL from sequence in one statement
put it in a SQL scalar function. Example:
CREATE function [dbo].SEQ_PERSON()
returns bigint as
begin
return
( select NEXTVAL
from openquery(oraLinkedServer, 'select SEQ_PERSON.NEXTVAL FROM DUAL')
)
end
I ended up having to iterate through all the records and set the ID value individually. Messy and slow, but it seems to be the only option in this scenario.
Very easy Just Use a CURSOR to Iterate with the code :
SELECT NEXTVAL AS SQ from OPENQUERY(MYSERVER, 'SELECT AC2012.NAME_SEQNO.NEXTVAL FROM DUAL')
So you can embed this select statement in any Sql statement, and Iterate by the CURSOR.
PS:
DECLARE SQCURS CURSOR
FOR SELECT (SELECT NEXTVAL AS SQ FROM OPENQUERY(MYSERVER,
'SELECT ORCL.NAME_SEQNO.NEXTVAL FROM DUAL')),
psn.BirthDate, psn.FirstName, psn.MiddleName, psn.LastName, c.REGION_CODE
FROM Person psn
LEFT JOIN MYSERVER..ORCL.COUNTRY c ON c.COUNTRY_CODE = psn.Country
OPEN SQCURS
FETCH NEXT FROM SQCURS ;
I hope that help

openquery giving different results

I have 2 similar queries
select *
from openquery(powerschool,
'select *
from TEACHERS
where teachernumber is not null
and schoolid=''1050''
and teacherloginid is not null
order by teachernumber')
and
SELECT *
from openquery(powerschool,
'SELECT NVL(teachernumber,'''')
from TEACHERS
where teachernumber is not null
and schoolid=''1050''
and teacherloginid is not null
order by teachernumber')
The first one is giving me 182 rows while the second one gives me 83.
What's wrong with the queries?
Second query never would return a null for the teachers table because of the NVL() so it could return more records depending on the data.
basically the " and teacherloginid is not null " never gets hit because you replace the nulls with ""
Just thoughts...
Same server? That is, linked server is different in target or credentialss o you are reading a different "TEACHERS" table
What does running both linked SQL statement actually on the linked server (not locally) give you?