Dynamic Stored Procedure in Sql Server 2005 - stored-procedures

Is it possible to write a stored procedure with dynamic parameters in sql server 2005

Technically no, but there's a workaround: temp tables. Create a temp table, then set up your stored procedure to read its configuration from the temp table.
Here's an example of how to call it:
CREATE TABLE #inputParams (ParamName VARCHAR(20), ParamValue VARCHAR(20))
INSERT INTO #inputParams (ParamName, ParamValue) VALUES ('First Name', 'John')
INSERT INTO #inputParams (ParamName, ParamValue) VALUES ('Last Name', 'Doe')
EXEC dbo.USP_MyStoredProcedure
and then inside your stored procedure, you could retrieve whatever parameters you needed by checking for the existence of that temp table, and querying the parameters from it like this:
CREATE PROCEDURE dbo.USP_MyStoredProcedure AS
DECLARE #FirstName VARCHAR(20)
SET #FirstName = SELECT ParamValue FROM #inputParams WHERE ParamName = 'First Name'
GO
That way, your stored procedure's number of parameters never changes, which makes it easier for some dev applications to call it over time, but this is reeeeeally dangerous. From the outside of the stored proc, you never have any idea what version of the stored proc you're calling, and whether or not it's going to do anything with the parameters you're sending in.
What you might think about instead is abstracting away your stored proc inside another stored proc as a wrapper.

No, both the count and parameter types are fixed as part of the stored procedure declaration.

If there's a discrete set of parameters you could pass them into the sproc as XML. Then you can shred the XML into variables inside the body of the sproc e.g.
CREATE PROCEDURE MyDynamicStoredProc
#ParameterXML XML
AS
SET NOCOUNT ON
DECLARE #Parameter1 NVARCHAR(50)
DECLARE #Parameter2 INT
SET #Parameter1 = #ParameterXML.value('/Root/Parameters/StringParameter/#Value','nvarchar(50)')
SET #Parameter2 = #ParameterXML.value('/Root/Parameters/IntegerParameter/#Value','int')
...
NB: My XQuery-fu is weak, don't rely on this example!

Related

How to assign default property value for IN parameters in teradata stored procedure

Need to develop a stored procedure to insert values into a table. Consider the table has 5 columns, where not all columns values are mandatory for user inputs. The DDL for stored procedure will be like
CREATE OR REPLACE PROCEDURE UPDATE_EMPLOYEE_INFO
(IN EMPLOYEE_NUMBER CHAR(10),
IN EMP_DEPT CHAR(3),
IN PHONE_NUMBER CHAR(4),
IN JOB CHAR(8),
IN ELEVEL SMALLINT)
Begin
--- Insert query here ---
End
This procedure can be execute using commands
CALL UPDATE_EMPLOYEE_INFO(1,'',1234567890,'admin','')
However,columns EMP_DEPT and ELEVEL are not mandatory fields to have values. How can I mention in stored procedure call to take default values like below.
CALL UPDATE_EMPLOYEE_INFO(1,DEFAULT,1234567890,'admin',DEFAULT).
Basically, I want to achieve something kind of this in link using teradata - https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/sqlp/rbafyprocdefaults.htm
There are no optional parameters. All parameters are mandatory. So you would probably have to pass in optional paramters as null and then write some conditional logic into your stored proc based on whether the parameter is null.
For example:
CALL UPDATE_EMPLOYEE_INFO(1,NULL,1234567890,'admin',NULL)
The Teradata documentation says:
Rules For Specifying Input And Output Parameters
Call arguments consisting of input and output parameters must be
submitted with a CALL statement. No default parameter values can be
defined at the time a procedure is created; the CALL returns an error
if the required call arguments are not specified.
https://info.teradata.com/HTMLPubs/DB_TTU_16_00/index.html#page/SQL_Reference/B035-1146-160K/cum1472240816735.html

DB2 calling stored Procedure in conditional statement

I need to query a stored procedure and on the basis of result set of that procedure need to make decisions in conditional statement
For instance I have a stored Procedure "Main_SP"
Now if result of "Main_SP" is 'null' then the result should be 'Tweety', but if th result set is not null then result set should be retrieved,
how to do it?
I tried following and some other but none worked.
SELECT
case Main_SP('MyVariable')
when 'null'
then 'Tweety' end
FROM SYSIBM.SYSDUMMY1 WITH UR
SELECT
case Main_SP('MyVariable')
when null
then 'Tweety' end
FROM SYSIBM.SYSDUMMY1 WITH UR
It is failing the condition, In first command when even it is 'null' it is not printing 'Tweety'.
and while using second, Getting error that 'Null' is not valid in the context.
I don't believe you can use a stored procedure that way.
A stored procedure can return data in two ways
As a result set
in an output or input/output parm
You're not using option 2 and I don't think a result set is ever NULL. There might be no records, but the RS itself isn't NULL. In addition, from what I can see in the manuals, processing a RS from a stored proc inside another stored proc in DB2 requires you to declare an allocate result set locators. But I've never done this.
If your procedure returns a single value or null, you'd be better served by defining it as a function with a return value. Then your code would be simply:
SELECT
COALESCE(Main_Fnc('MyVariable'),'Tweety')
FROM
SYSIBM.SYSDUMMY1 WITH UR
You can't call a stored procedure as part of an SQL fullselect; you would need to have the client that calls the stored procedure handle this logic. If you must do it on the server, implement a new stored procedure that calls Main_SP itself and contains your logic to interpret the result.

How to specify a parameter as collection in Commandtext

I am using SqlCommandProvider and I need to get some data for each id in an id collection
let ids=["B058A99-C4B2-4CC3-BA9F-034B1F1ECCBD";"A09C01C-D51B-41C1-B44C-0995DD285088"]
[<Literal>]
let qLogo ="""SELECT Id,LogoUrl FROM Hotels WHERE Id IN (#IDS)"""
let queryLogo = new SqlCommandProvider<qLogo,constring>()
queryLogo .Execute(ids)//i need to be able to pass a collection here
`
Long story short, SqlCommandProvider is not even correct type provider to do this (assuming you don't consider string concatenation to build query). The reason is SQL Server only accepts array parameters through calling stored procedure and passing a Table Valued Parameter.
So, to call a stored procedure you need an SqlProgrammabilityProvider to achieve this. But you'll have to create Table Type and Stored Procedure up-front, as described in type provider documentation (scroll down to "Table-valued parameters (TVPs)" section).
Relevant discussion: How to use SQL IN statement in fsharp.data.sqlclient?

Replace stored procedure with MyBatis mapping

I can not find an example of mapping in MyBatis that I can replace the below code with.
"if sqlcode <> 0" If no update takes place then do an insert
Any sugestions? :)
as
begin
execute SetDefaultIsolationLevel
update COMPANYLEVEL
set
companylevelid = #companylevelid,
companynameid = #companynameid,
level = #level,
memo = #memo,
operator = #operator,
changed = getdate(*)
where
companynameid = #companynameid
if sqlcode <> 0
BEGIN
insert into COMPANYLEVEL
(companylevelid,companynameid,level,memo,operator,changed)
values
(#companylevelid,#companynameid,#level,#memo,#operator,getdate(*))
END
commit transaction
end
I don't think MyBatis has any mapping to say "try an update, if that fails do an insert". If you want that done in one round trip to the database, then a stored procedure is appropriate. You can call this stored procedure from MyBatis, but the if/else logic would be in the stored proc.
If you are trying to get rid of the stored proc, then you'll need a two step check in your code. An update in MyBatis returns the number of rows updated (via the JDBC driver), so if that is zero, then you can call a MyBatis insert mapping. In cases where an insert occurs, it would require two round trips to the database.
You could also do an "upsert" using a MERGE statement in a stored proc, but that of course isn't related to MyBatis other than MyBatis can call your stored proc. It looks like you are using Sybase? If so, I'm not sure if Sybase has upserts - link to research: Upsert (update or insert) in Sybase ASE?

how do i execute a stored procedure with vici coolstorage?

I'm building an app around Vici Coolstorage (asp.net version). I have my classes created and mapped to my database tables and can pull a list of all records fine.
I've written a stored procedure where the query jumps across databases that aren't mapped with Coolstorage, however, the fields in the query result map directly to one of my classes. The procedure takes 1 parameter.
so 2 questions here:
how do i execute the stored procedure? i'm doing this
CSParameterCollection collection = new CSParameterCollection();
collection.Add("#id", id);
var result = Vici.CoolStorage.CSDatabase.RunQuery("procedurename", collection);
and getting the exception "Incorrect syntax near 'procedurename'." (i'm guessing this is because it's trying to execute it as text rather than a procedure?)
and also, since the class representing my table is defined as abstract, how do i specify that result should create a list of MyTable objects instead of generic or dynamic or whatever objects? if i try
Vici.CoolStorage.CSDatabase.RunQuery<MyTable>(...)
the compiler yells at me for it being an abstract class.
There's a shortcut in CoolStorage to run a stored procedure. Simply prefix the stored procedure name with "!":
CSDatabase.RunQuery("!procedurename", collection);

Resources