TRANSACT SQL error 216 - sql-server

I have a Transact SQL script that creates a table AND a table value function based on that table which I invoke from another script using SQLCMD mode; for example:
:r .\MyTableScript.sql
All is working well, both at DB generation time and at execution time.
Now I split the script into two files to separate the function, I end up with something like this in the 'master script':
:r .\MyTableScript.sql
:r .\MyTableFunctionScript.sql
All works well to generate the database, however when I call the function I get error "216 Parameters were not supplied for the function".
This is weird.
If I call the function with the wrong number of parameters I get the correct message, something like '... invalid number or arguments ...'; if I call the function with arguments of the wrong type then again I get the appropriate message about the wrong type for the arguments.
But when I call the function with the right arguments I get the aforementioned message.
I know that CREATE FUNCTION must be the first statement in a batch and it is. I also tried with and without semicolon's in the 'right' places.
Now, I put back the function into the same script file as the table itself (just after the DDL for the table) and regenerate the database and all is now working fine again.
I can leave it like this (the table and the function in one big script file), BUT I would prefer to spilt the table and the function scripts into two SQL scripts files.
What am I doing wrong?

Maybe you are passing the right number of arguments but one of them is NULL.

Related

Find Out List Of Objects Referenced In Snowflake Procedure

I want to get list of Objects referenced in Snowflake Procedure , let us say It is using Tables, Views Inside it , I want to find those items from Procedure definition , as currently there is no function in Snowflake that can provide this information.
GET_OBJECT_REFERENCES https://docs.snowflake.com/en/sql-reference/functions/get_object_references.html is function now only available for Views and not for Procedure.
Any pointers in scanning the definition of Procedure and figure out objects in it.
As Felipe pointed out, you can pass the name of a table or view as a parameter into the stored procedure. In that case there's no way to know what objects the SP will reference.
If your organization tends not to do that; if your SQL in stored procedures tends to be more along the lines of "select * from my_table" you can simply search for those references in the stored procedure code.
The following statement is crude, but effective. It could be developed and polished a lot, and it could miss references. It also only finds the first match, while a more useful query would return all and flatten out the array. I may have time to work on that a bit. It did find a lot in my test. It simply looks for the following pattern:
SQL Command ... Matching Clause for that Command ... Semicolon
The reason this works is that even if you don't terminate the SQL in the stored procedure, the JavaScript line should be terminated with a semicolon. JavaScript is comparatively forgiving of missing semicolons, but it should hit one eventually and match the SQL statement.
select PROCEDURE_CATALOG
,PROCEDURE_SCHEMA
,PROCEDURE_NAME
,ARGUMENT_SIGNATURE
,regexp_substr(PROCEDURE_DEFINITION, 'SELECT\\s.*FROM.*;|INSERT\\s.*INTO.*;|UPDATE\\s.*SET.*;|MERGE\\s.*INTO.*;|DELETE\\s.*FROM.*;|MERGE\\s.*USING.*;',1, 1, 'ims') STATEMENT
from MY_DATABASE.INFORMATION_SCHEMA.PROCEDURES
where STATEMENT is not null;
I write a lot of stored procedures, and to Felipe's point this returns a lot of rows like this for me:
select ${params.leftColumnList} from ${params.leftObject} order by ${leftTimestamp};`);
In those cases, you'd need to have someone who can read code figure out what it's referencing. In this case, the SP accepts parameters for those fields, so they could be any tables.

Print Statements from SQL file in command prompt

I am executing a SQL file which contains basic create table and lot of insert statements from command prompt. Since there are huge number of inserts, i want to track how many inserts are done. To do that i want to add few statements describing start and end of certain section in the sql file. I want this statement printed in the command prompt itself . Is there anyway i can do this?
Either print or message will do the trick. You can follow the examples inside each link.
In some specific cases you can also simply do SELECT "Some custom message...";

SSDT/SSIS Execute SQL Task not populating variable with query output

My Execute SQL Task uses a simple query that should be returning a single value. I want to write that value to a variable so that I can use it in a data flow task later but the result never seems to get written to my variable.
The SQL statement is simple:
select max (rec_id) from [dbo].[RX_BILLING_TEST]
and I believe that I've set up the task correctly:
When I execute the task, it completes successfully but the variables window shows that the value of my variable didn't update. I set breakpoints on variable value changed and on post execute but that didn't help.
As much as I hate errors, this is a case where I would appreciate getting one to point me in some direction. Any ideas what might be wrong?
In a similar case there are many things you have to check:
Try adding an alias to the aggregate function
select max (rec_id) AS Max_Rec_Id from [dbo].[RX_BILLING_TEST]
Check that your package doesn't have more than one variable User::v_Recid with different scopes. or that User::v_Recid scope's is Execute SQL Task. (it must be the Package)
Test your SQL Command using Sql Server Management Studio
Try adding the database name to your Command
select max (rec_id) AS Max_Rec_Id from [MyDB].[dbo].[RX_BILLING_TEST]

print or select inside SQLServer function

In SQLServer sometimes following the code without debugging is necessary. It is possible with print statement or with select statement. The problem is SQLServer does not allow these methods within the functions. That makes the complex function like the black box. I have tried to use write the messages to the text file with stored procedure within the function, however, it doesn't allow either.
Is there any way to track my code like print statement within the function.
Your statement
The problem is SQLServer does not allow these methods within the functions
is the problem and the answer at the same time. Yes: This is not allowed within functions.
When I've to deal with larger function code, I usually copy this code into a query window and test it externally. Doing so, you can use PRINT or SELECT ... INTO or any other approach to save some intermediate values.

error invoking procedure with multiple select commands

I have an SSIS package with a data flow task. The OLE DB source has an execute proc statement. It fails while saving with below error message.
an OLEDB record is available... The metadata could not be determined because the statement 'select appname....' in procedure is not compatible with the statement 'select appid....' in procedure
This proc has several select statements and returns the appropriate result set as per parameters passed. Any pointers to bypass this error?
So you're saying that the SP will return different meta data depending on the parameter passed? SSIS doesn't like this - it can't update the meta data dynamically at run time. i.e. if you create a package that splits or sorts on a certain column, then you run the SP and it doesn't return that column, or the same column is a different data type, what should SSIS do? It can't automatically work it out.
I suggest you create a data source for each possibility of result set returned and conditionally execute each on as required.
In short SP's returning optionally different datasets is often not a good idea, definitely not from an ETL perspective.
Here is some code that shows how to create dynamically built output, (you could use the same method with just one output), but you'll still face the same problems downstream.
http://www.codeproject.com/Articles/32151/How-to-Use-a-Multi-Result-Set-Stored-Procedure-in
I ran into this issue as well. In my case, the result returned looked identical no matter which branch was executed, the difference was just in how that result was obtained (including different source tables). I simply executed all the cases with a union, and each "where" clause included the conditions for its execution instead of using "if" logic to choose a query.

Resources