Stored Procedure Question - Conditional Return Value?
Here's the stored procedure:
CREATE PROCEDURE dbo.sp_get_setting
@BankID char(4)='',
@SectionID varchar(50)='',
@KeyID varchar(50)=''
AS
BEGIN
DECLARE @query varchar(255)
SET @query = 'SELECT [ValueID] FROM Settings WHERE BankID = "' + @BankID +'" AND SectionID = "' + @SectionID + '" AND KeyID = "' + @KeyID + '"'
EXEC(@query)
--IF *** "good" value ***'' return 0 --Success!
--ELSE return -1 --value not found or blank
END
GO
I am using this stored proc in an MFC C++ application using SQL Server and an ODBC connection. I've worked all of the C++ syntax out to "get" the value from the [ValueID] I am looking for. I can also retrieve the "return" value.
What I am having trouble doing is testing the condition in which the stored proc will return an assigned value based on the value it finds in the query.
What I would like to return is a "0" if the data row exists AND the data is not NULL or blank. If the data row does not exist, or the data is NULL or blank, I want to return a -1. The two remarked lines of code in the above stored proc is where I am talking about. I need a way to find some code to replace "*** "good" value ***".
Can someone help me out with the syntax here? Thanks - Jim
[1421 byte] By [
vwduud] at [2007-11-19 2:44:56]

# 1 Re: Stored Procedure Question - Conditional Return Value?
CREATE PROCEDURE dbo.sp_get_setting
@BankID char(4)='',
@SectionID varchar(50)='',
@KeyID varchar(50)=''
AS
BEGIN
IF EXISTS(SELECT [ValueID] FROM Settings WHERE BankID = @BankID AND SectionID = @SectionID AND KeyID = @KeyID AND [ValueID] IS NOT NULL)
RETURN 0 --IF *** "good" value ***'' return 0 --Success!
return -1 --value not found or blank
END
Why not?
Krzemo at 2007-11-9 13:39:14 >

# 2 Re: Stored Procedure Question - Conditional Return Value?
IF EXISTS(SELECT [ValueID] FROM Settings WHERE BankID = @BankID AND SectionID = @SectionID AND KeyID = @KeyID AND [ValueID] IS NOT NULL)
Why not?
I had a problem overcoming syntax errors if not first setting up the query string then calling the query through the EXEC command. It did not like assignments as shown above in the SELECT clause's argument list. Any suggestions?
vwduud at 2007-11-9 13:40:13 >

# 3 Re: Stored Procedure Question - Conditional Return Value?
1) Dynamic vs static
* When U made call "EXEC(@query)" no syntax checking is made until runtime.
* If U pass NULL to any of parameters yours "@query" also becomes NULL.
* Wat if user pass " ';USE master;DROP DATABASE YourDatabase" in @SectionID
etc. etc.
2) It is usualy bad design when using dynamic query execution (the way U do). There is no reason to do it dynamically
3)
It did not like assignments as shown above in the SELECT clause's argument listWhat assigments? there are only comparisions.
4) If U must do dynamically - look below:
CREATE PROCEDURE InsertSales @PrmOrderID INT, @PrmCustomerID INT,
@PrmOrderDate DATETIME, @PrmDeliveryDate DATETIME
AS
DECLARE @InsertString NVARCHAR(500)
DECLARE @OrderMonth INT
-- Build the INSERT statement.
SET @InsertString = 'INSERT INTO ' +
/* Build the name of the table. */
SUBSTRING( DATENAME(mm, @PrmOrderDate), 1, 3) +
CAST(DATEPART(yy, @PrmOrderDate) AS CHAR(4) ) +
'Sales' +
/* Build a VALUES clause. */
' VALUES (@InsOrderID, @InsCustID, @InsOrdDate,' +
' @InsOrdMonth, @InsDelDate)'
/* Set the value to use for the order month because
functions are not allowed in the sp_executesql parameter
list. */
SET @OrderMonth = DATEPART(mm, @PrmOrderDate)
EXEC sp_executesql @InsertString,
N'@InsOrderID INT, @InsCustID INT, @InsOrdDate DATETIME,
@InsOrdMonth INT, @InsDelDate DATETIME',
@PrmOrderID, @PrmCustomerID, @PrmOrderDate,
@OrderMonth, @PrmDeliveryDate
GO
5) IF U must concate string use this:
SET @query = 'SELECT [ValueID] FROM Settings WHERE BankID = "' + IsNull(@BankID,'') +'" AND SectionID = "' + IsNull(@SectionID,'') + '" AND KeyID = "' + IsNull(@KeyID,'') + '"'
or:
IF @BankID IS NULL SET @BankID=''
...
SET @query = 'SELECT [ValueID] FROM Settings WHERE BankID = "' + @BankID +'" AND SectionID = "' + @SectionID + '" AND KeyID = "' + @KeyID + '"'
6) If U want not to do search based on parameters that are set to NULL
Dynamic: exclude parameters that are NULL
STATIC
SELECT [ValueID] FROM Settings WHERE BankID = IsNull(@BankID,BankID) AND SectionID = IsNull(@SectionID,SectionID) + '" AND KeyID =IsNull(@KeyID,KeyID)
The End.
If it will not help U please specify what exactly U want to achieve,what syntax errors you trying to overcome and why U don't do it in standard way .
Best regards,
Krzemo.
Krzemo at 2007-11-9 13:41:21 >

# 4 Re: Stored Procedure Question - Conditional Return Value?
If it will not help U please specify what exactly U want to achieve,what syntax errors you trying to overcome and why U don't do it in standard way .
Best regards,
Krzemo.
I would be more than happy to learn to do this in a "standard way". Although I have years of non-database experience in MFC and C++, SQL Server and stored procedures are relatively new to me.
If, by "standard", you are referring to the example in the first reply to this post, I tried that. It does not have any syntax errors, yet it also does not return the value from the SELECT statement, when using Query Analyzer.
vwduud at 2007-11-9 13:42:14 >

# 5 Re: Stored Procedure Question - Conditional Return Value?
Try this:
CREATE PROCEDURE dbo.sp_get_setting
@BankID char(4)='',
@SectionID varchar(50)='',
@KeyID varchar(50)=''
AS
BEGIN
SELECT [ValueID] FROM Settings WHERE BankID = @BankID AND SectionID = @SectionID AND KeyID = @KeyID AND [ValueID] IS NOT NULL
IF EXISTS(SELECT [ValueID] FROM Settings WHERE BankID = @BankID AND SectionID = @SectionID AND KeyID = @KeyID AND [ValueID] IS NOT NULL)
RETURN 0 --IF *** "good" value ***'' return 0 --Success!
return -1 --value not found or blank
END
I was shure that U want only to have return value set. :)
IF U want ouput of that value in Query Analizer U must put this code:
DECLARE @Stat INT
EXEC @Stat=sp_get_setting ..params here..
SELECT @Stat Status
It works also with my code in first post.
By the way, Isn't it better to check in application if any rows has returned?
Why U want SQL to do this check for U.
Best regards,
Krzemo.
Krzemo at 2007-11-9 13:43:23 >

# 6 Re: Stored Procedure Question - Conditional Return Value?
I was shure that U want only to have return value set. :)
IF U want ouput of that value in Query Analizer U must put this code:
DECLARE @Stat INT
EXEC @Stat=sp_get_setting ..params here..
SELECT @Stat Status
It works also with my code in first post.
By the way, Isn't it better to check in application if any rows has returned?
Why U want SQL to do this check for U.
Best regards,
Krzemo.
Hmmm, two things: the return value for [ValueID] is a string of 255 characters, not an INT. I am not sure the solution above (DECLARE @Stat INT...) will provide me with the info I am looking for.
As for your second question, here is a brief summary of what this stored proc is needed for:
sp_get_setting retrieves application settings from a table. These "settings" are like those you might get from the Registry or an INI file to initialize application variables upon startup, and throughout the use of the application. An example might be a path like: "C:\Program Files\C&A Associates\ProofPC\Images". This "setting" provides the application with "where" to save images acquired by the scanner.
This application initially was using Access as its database, as the application had few users and did not need a robust solution such as SQL Server. This application was also designed with the "settings" built into a database table (as opposed to a local INI file or in Registry settings). In addition to multiple users, there is a lot of database traffic in just retrieving these values (although there is a cache feature that helps somewhat). The goal has been to quickly get SQL Server integrated to increase performance with a greater number of users, and make its data transaction more efficient.
For the Access DB, all SQL calls where direct (no QueryDefs, etc). A noticeable increase in retrieving these settings was observed even with my initial attempt with my version of the stored procedure.
When using Access, the application would retrieve each "setting" with the following code:
query.Format("SELECT [" + cstrValue + "] FROM Settings WHERE BankID='%s' AND " + cstrSection + "='%s' AND " + cstrKey + "='%s'", m_bankID, section, key);
CODBCRecordset recordset(&m_database);
TRY recordset.Open(query, CRecordset::snapshot);
It's attempt to see if a "setting" record was found was performed with the following code:
if (! recordset.IsEOF())
{
val = recordset.Field(cstrValue);
}
else
{
val = def;
}
recordset.Close();
In other words, if a value was not found, the "setting" we were looking for, which gets set to the variable "val" gets set to a default value. Although this works fine, I would like to reduce the C++ code, and take use of both the return value from the table and the return value from the success (or failure) of the attempted query. I can do this with other methods, but would like to learn and understand the use and efficiency by using stored procedures. I also like the idea of localizing this functionality in the DB for reuse in other applications, simplifying their future development.
vwduud at 2007-11-9 13:44:22 >

# 7 Re: Stored Procedure Question - Conditional Return Value?
First I will explain some misunderstanding.
Return value (in stored procedure or C,C++ function) is value returned by return statement. So if there is "RETURN 1" the return value is 1.
In stored procedures (in SQL Server) the return values have type of INT (long in C,C++ or System.Int32 in .NET) so if you want see in the return value in SQL Query Analizer U have to write code like this:
DECLARE @Stat INT
EXEC @Stat=sp_get_setting ..params here..
SELECT @Stat Status
It will convert return value to result set.
When U write that U need to translate code:
--IF *** "good" value ***'' return 0 --Success!
--ELSE return -1 --value not found or blank
I've translated it for U:
IF EXISTS(SELECT [ValueID] FROM Settings WHERE BankID = @BankID AND SectionID = @SectionID AND KeyID = @KeyID AND [ValueID] IS NOT NULL)
RETURN 0 --IF *** "good" value ***'' return 0 --Success!
return -1 --value not found or blank
And it return only return value (no result sets send to user)
Code below return result set (not a return value)
SELECT [ValueID] FROM Settings WHERE BankID = @BankID AND SectionID = @SectionID AND KeyID = @KeyID AND [ValueID] IS NOT NULL
If U combine above 2 codes U will have return value and result set in one procedure.
If U want to return VARCHAR(255) (not to return resultset with 1 value) U shuld use (stored) function or procedure with output parameter.
In next post I will send new suggestion from my expirience..
Krzemo at 2007-11-9 13:45:24 >

# 8 Re: Stored Procedure Question - Conditional Return Value?
So U need procedure with default settings?
look here:
version with output parameter (no result set):
CREATE PROCEDURE dbo.sp_get_setting
@BankID char(4)=''
,@SectionID varchar(50)=''
,@KeyID varchar(50)=''
,@Value varchar(255) OUTPUT
AS
SELECT @Value=ValueColumn
FROM Settings
WHERE BankID = @BankID AND SectionID = @SectionID AND KeyID = @KeyID AND ValueColumn IS NOT NULL
IF @Value IS NULL SET @Value='Default Value'
RETURN 0
version with result set (1 row 1 value)
CREATE PROCEDURE dbo.sp_get_setting
@BankID char(4)=''
,@SectionID varchar(50)=''
,@KeyID varchar(50)=''
AS
DECLARE @Value varchar(255)
SELECT @Value=ValueColumn
FROM Settings
WHERE BankID = @BankID AND SectionID = @SectionID AND KeyID = @KeyID AND ValueColumn IS NOT NULL
IF @Value IS NULL SET @Value='Default Value'
SELECT @Value ValueReturned
RETURN 0
version with function:
CREATE FUNCTION dbo.sp_get_setting
( @BankID char(4)=''
,@SectionID varchar(50)=''
,@KeyID varchar(50)=''
) RETURNS VARCHAR(255)
AS
BEGIN
DECLARE @Value varchar(255)
SELECT @Value=ValueColumn
FROM Settings
WHERE BankID = @BankID AND SectionID = @SectionID AND KeyID = @KeyID AND ValueColumn IS NOT NULL
IF @Value IS NULL SET @Value='Default Value'
RETURN @Value
END
As U see "setting" is returned (in result set or output parameter) always. If there is no valid (not null) parameter than default value is returned.
Best regards,
Krzemo.
Krzemo at 2007-11-9 13:46:27 >

