Reusing Value of a subquery in Else clause - sql

is there any way i can use the value of X in the if clause in the else clause
if #bid_value>(SELECT MAX(bid_value) AS X FROM dbo.auctionDetails WHERE status = 0 AND vehicle_id=#vid GROUP BY vehicle_id)
BEGIN
//some code
END
ELSE IF X=NULL
BEGIN
//some code
END

Why don't you create a var for the value?
DECLARE #maxValue INT
SELECT #maxValue = MAX(bid_value)
FROM dbo.auctionDetails
WHERE status = 0 AND vehicle_id = #vid
IF (#bid_value > #maxValue)
BEGIN
// some code
END
ELSE IF (#maxValue IS NULL)
BEGIN
// some code
END
A comment about how you are getting the MAX value: As you are filtering by vehicle_id = #vid, you don't need GROUP BY clause since you will get results for only one value of vahicle_id

You would typically assign the results of the query to a variable.
If you are running SQL Server:
DECLARE #max_bid_value INT;
SELECT #max_bid_value = MAX(bid_value)
FROM dbo.auctionDetails
WHERE status = 0 AND vehicle_id = #vid;
IF #bid_value > #max_bid_value
BEGIN
//some code
END
...
Note that I removed the GROUP BY clause from the original query - I think that this makes it clearer that it should always return a scalar value.
Note that if you want to check if a variable is null, you need #bid is null rather than #bid = null.

Your query should be like below :
DECLARE #X INT
SET #X = (SELECT MAX(bid_value) AS X FROM dbo.auctionDetails WHERE status = 0 AND vehicle_id=#vid);
IF #bid_value>#MAX
BEGIN
//some code
END
ELSE IF X=NULL
BEGIN
//some code
END

Related

SQL Server - CASE on where clause

I'm working on a stored procedure that is a select query. Under the WHERE clause I am filtering the return results to return only if there is a PageTitle= 'STA'
Here is am example of my query :
#InputCountryId INT,
#InputIndustryId INT
AS
BEGIN
SELECT
r.IdCountry,
r.IdIndustry,
r.PageTitle,
r.IndustryName
From dbo.Reports r
WHERE
r.IdCountry = #InputCountryId
r.IdIndustry = #InputIndustryId
r.PageTitle = 'STA'
END
The ending condition r.PageTitle I would like it to be applied ONLY IF InputCountry = 1 if not; do not include the filter.
I've attempted this by including a CASE. I am having a syntax error any time I try and introduce this case. Is this something that is possible? Am I implementing it incorrectly?
Here is an example of the stored proc with the CASE included.
#InputCountryId INT,
#InputIndustryId INT
AS
BEGIN
SELECT
r.IdCountry,
r.IdIndustry,
r.PageTitle,
r.IndustryName
From dbo.Reports r
WHERE
r.IdCountry = #InputCountryId
r.IdIndustry = #InputIndustryId
CASE WHEN #InputCountryId = 1 THEN
r.PageTitle = 'STA'
END
END
Try it this way:
WHERE
r.IdCountry = #InputCountryId and
r.IdIndustry = #InputIndustryId and
(#InputCountryId <> 1 or r.PageTitle = 'STA')
You dont need case statement. You can use OR clause
WHERE
r.IdCountry = #InputCountryId
r.IdIndustry = #InputIndustryId
(#InputCountryId != 1 OR r.PageTitle = 'STA')
this only filters PageTitle with STA when InputCountry is 1
I can't test with your data, but here is a CASE in a WHERE clause that works.
DECLARE #Variable INT = 3
SELECT GETDATE()
WHERE 1 =
CASE
WHEN #Variable = 1 THEN 1
WHEN #Variable = 3 THEN 1
WHEN #Variable = 5 THEN 1
ELSE 0
END

Apply IF conditional at the end of the query

I'm new in sql server and I have WHERE clause like this:
WHERE[D].[IsLocked] = 0
AND(#StartDate IS NULL OR ISNULL([TA].[ModifiedDate], [TA].[CreationDate]) >= #StartDate)
AND(#EndDate IS NULL OR ISNULL([TA].[ModifiedDate], [TA].[CreationDate]) <= #EndDate)
AND((CASE WHEN[T].[TaskStatusId] = '09E02513-00AD-49E3-B442-A9ED2833FB25'
THEN 1 ELSE 0 END) = #Completed)
AND((#FilterEmpKey IS NULL AND[TA].[EmpKey] = #CurrentEmpKey)
OR (ISNULL([TA].[ModifiedAssignedBy], [TA].[AssignatedBy]) = #FilterEmpKey
AND[TA].[EmpKey] = #CurrentEmpKey))
But now I want to add if conditional in order to add more filters at the end of query like:
IF(#FilterEmpGuid IS NOT NULL)
AND[TA].[EmpKey] = #CurrentEmpKey
AND[TA].[AssignatedBy] = #CurrentEmpKey
AND[TA].[EmpKey] = #FilterEmpKey
But I get:
The multi-part identifier [TA].[EmpKey] could not be bound
What am I doing wrong?
IF conditionals are only for use outside sql queries, such as in procedures etc.
In a query itself you are limited to AND, OR and CASE statements, so you will need to rewrite your IF conditional for this:
AND (#FilterEmpGuid IS NULL
OR (
[TA].[EmpKey] = #CurrentEmpKey
AND[TA].[AssignatedBy] = #CurrentEmpKey
AND[TA].[EmpKey] = #FilterEmpKey
))
You could move the additional filter options into a scalar function.
If you know the additional fields that may be filtered, you may be able to get away with something like:
CREATE FUNCTION dbo.ExtendFilter(
#column_value VARCHAR(50), #param_value VARCHAR(50)
)
RETURNS BIT
AS
BEGIN
DECLARE #return BIT = 1; -- default RETURN to 1 ( include ).
IF ( NULLIF( #param_value, '' ) IS NOT NULL )
BEGIN
-- compare the column's value to the param value
IF ( #column_value <> #param_value )
SET #return = 0; -- don't include this record.
END
RETURN #return;
END
GO
And then use it like:
WHERE
{ other WHERE stuff }
AND dbo.ExtendFilter( [TA].[EmpKey], #CurrentEmpKey ) = 1
AND dbo.ExtendFilter( [TA].[AssignatedBy], #CurrentEmpKey ) = 1
AND dbo.ExtendFilter( [TA].[EmpKey], #FilterEmpKey ) = 1
Mind you this is just an example. You'd want to check #pram_value for NULL, etc...

Uniqueidentifier as parameter in SQL Server Function

I have created a Function in SQL Server 2012 that I will use in a Check Constraint on a table.
The function works as expected if I do:
SELECT [dbo].[CheckValidCardnumberForShellTankingen] ('700678036658047691' ,'2925CA00-6DD5-4F9D-AB0E-AA15DBBD388B')
But when I try to set the expression in Check Constraint so:
([dbo].[CheckValidCardnumberForShellTankingen]([Volledig kaartnummer],[RollBackCode])=(1))
I get a Messaage: "Error validating constraint 'CK_MyConstraint'"
I use the Uniqueidentifier in a Where clause and the strange thing is if I replace the parameter with string containing the Uniqueidentifier I dont get this error.
Here is the Function:
-- =============================================
-- Author: Anders Pedersen
-- Create date: 2015-02-13
-- Description: Check of the Cardnumber of a transaction is valid.
-- =============================================
CREATE FUNCTION [dbo].[CheckValidCardnumberForShellTankingen]
(
-- Add the parameters for the function here
#Cardnumber NvarChar(50),
#RollBackCode NvarChar(200)
)
RETURNS BIT
AS
BEGIN
-- Declare the return variable here
DECLARE
#Result BIT
,#ResultLenght BIT
,#ResultPrefix BIT
,#CardLenght INT
,#SupplierID INT
,#UseCardnumber BIT
,#Prefix NvarChar(50)
-- Add the T-SQL statements to compute the return value here
SET #Result = 0
SET #ResultLenght = 0
SET #ResultPrefix = 0
SET #CardLenght = -1
SET #SupplierID = -1
SET #UseCardnumber = 0
SET #Prefix = ''
-- Get the UseCardnumber and the SupplierID
SELECT #UseCardnumber = C.UseCardNumber, #SupplierID = F.SupplierID
FROM Client C INNER JOIN
ClientFileUploads F ON C.ClientID = F.ClientID
WHERE F.RollBackCode = #RollBackCode
--WHERE F.RollBackCode = '2925CA00-6DD5-4F9D-AB0E-AA15DBBD388B'
-- Only carry out the check if the Client use Cards else set the check to True (1)
IF #UseCardnumber = 1
BEGIN
SELECT #CardLenght = [CardNumberLenght], #Prefix = ISNULL([Prefix],'') FROM [dbo].[Supplier] AS S WHERE S.SupplierID = #SupplierID
IF (#CardLenght IS NULL) OR (#CardLenght = 0)
BEGIN
SET #ResultLenght = 1
END
ELSE
BEGIN
IF (LEN(#Cardnumber) - #CardLenght)= 0
BEGIN
SET #ResultLenght = 1
END
ELSE
BEGIN
SET #ResultLenght = 0
END
END
IF SUBSTRING(#Cardnumber, 1, LEN(#Prefix)) = #Prefix
BEGIN
SET #ResultPrefix = 1
END
ELSE
BEGIN
SET #ResultPrefix = 0
END
IF ((#ResultLenght = 1) AND (#ResultPrefix = 1))
BEGIN
SET #Result = 1
END
ELSE
BEGIN
SET #Result = 0
END
END
ELSE
BEGIN
SET #Result = 1
END
-- Return the result of the function
RETURN #Result
END
GO
If #RollBackCode is a uniqueidentifier, I recommend making the parameter a uniqueidentifier and not a varchar.
As Rhys Jones points out, you shouldn't use a UDF in a check constraint.
See
https://dba.stackexchange.com/questions/22297/udf-in-check-constraint-downside
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/078b720f-faac-425c-b51a-33bcecb263d2/check-constraint-with-udf-problem-with-lots-of-data?forum=transactsql
http://sqlblog.com/blogs/tibor_karaszi/archive/2009/12/17/be-careful-with-constraints-calling-udfs.aspx
If you need to check in a trigger and roll back -- SQL Server - After Insert/ For Insert - Rollback

triggers are not firing when I use bulk copy in code

I have a trigger called "updateFriendlyURLTitle" in dbo.Aritcle table. When a individual article inserted, that trigger working fine.
But in article importing process: I've used the following codes. This codes make copy article but it doesn't fire the trigger to generate FriendlyUrl.
private void WriteArticlesToDatabase<TData>(DataSet ds, SqlTableDetails tableDetails, IEnumerable<TData> newArticles, SqlTransaction transaction)
{
var dt = WriteToDataTable(ds, tableDetails.Table, newArticles);
using (var bulkCopy = new SqlBulkCopy(_destConnection, SqlBulkCopyOptions.FireTriggers, transaction))
{
bulkCopy.DestinationTableName = tableDetails.ToString();
bulkCopy.WriteToServer(dt);
}
}
My trigger is like below:
ALTER TRIGGER [dbo].[updateFriendlyURLTitle] ON [dbo].[Articles]
AFTER INSERT, UPDATE
AS
IF ##ROWCOUNT > 0
BEGIN
IF COLUMNS_UPDATED() != 0x0000200000100000 -- columns other than newsCounterViews have been updated
BEGIN
DECLARE #oldestfulllucenebuild AS DATETIME
DECLARE #deletedNewsID INT
DECLARE #newsStatus BIT
DECLARE #maxcalcimp AS FLOAT
DECLARE #insertedCalculatedImportance INT
DECLARE #insertedNormalisedCalculatedImportance INT
DECLARE #insertedSeoURLTitle VARCHAR(255)
select #oldestfulllucenebuild = min(luceneIndexCreatedDate)
from Lucene_Indexes
where luceneIndexType = 'news'
select #oldestfulllucenebuild = dateAdd(year,10,#oldestfulllucenebuild)
select #maxcalcimp = cast(#oldestfulllucenebuild as float) * 48 *100 --the max importance
select #insertedCalculatedImportance = inserted.newsCalculatedImportance,
#insertedNormalisedCalculatedImportance = inserted.newsNormalisedCalculatedImportance,
#insertedSeoURLTitle = inserted.newsSeoURLTitle
from inserted
--if the current statement is updating the importance or seo columns then do not perform this query (so it doesn't get stuck in a loop)
IF (NOT UPDATE(newsCalculatedImportance)) AND (NOT UPDATE(newsNormalisedCalculatedImportance)) AND (NOT UPDATE(newsSeoURLTitle))
OR
--if it is inserting a new record then perform the query
(#insertedCalculatedImportance = 0 AND #insertedNormalisedCalculatedImportance is null AND #insertedSeoURLTitle = '')
BEGIN
update Articles
set newsCalculatedImportance = cast(cast(inserted.newsArticledate as float )*48 + inserted.newsimportance AS int)
, newsNormalisedCalculatedImportance = (1/ #maxcalcimp) * cast(cast(inserted.newsArticledate as float )*48 + inserted.newsimportance AS int)
, newsSeoURLTitle = LEFT(dbo.getSEOURLTitle(inserted.newstitle), 255)
from Articles inner join inserted on
Articles.newsid = inserted.newsid
END
SELECT #deletedNewsID = newsID, #newsStatus = newsStatus
FROM inserted
IF(#newsStatus = 0)
BEGIN
DELETE FROM tbl_DenormalisedNews WHERE newsid = #deletedNewsID
DELETE FROM News_Deleted_DateTime
WHERE NewsID = #deletedNewsID
INSERT INTO News_Deleted_DateTime
VALUES (#deletedNewsID, getDate())
END
ELSE
BEGIN
--news status is 1, remove it from the news_deleted_datetime table if it exists
DELETE FROM News_Deleted_DateTime
WHERE NewsID = #deletedNewsID
END
-- newsImage1 optimisation: if newsImage1 = '' THEN has_image = FALSE ELSE has_image = TRUE
IF UPDATE(newsImage1)
UPDATE Articles SET
has_image = CASE WHEN Articles.newsImage1 = '' THEN CAST(0 AS bit) ELSE CAST(1 AS bit) END
FROM
Articles INNER JOIN inserted ON Articles.newsid = inserted.newsid
END
END
Does anyone knows how to fix this issue ?

comparing three variables

I have three integer variables: firstCount, secondCount, thirdCount. I need to compare it and to output the result. I'm bad at SQL, but C# code is something like this:
if(firstCount == secondCount == thirdCount)
return true;
else
return false;
One way (2008 syntax).
SELECT CAST(CASE
WHEN COUNT(DISTINCT C) = 1 THEN 1
ELSE 0
END AS BIT)
FROM (VALUES (#firstCount),
(#secondCount),
(#thirdCount)) t (C)
declare #first int
, #second int
, #third int
select #first = 0
, #second = 0
, #third = 0
select case when (#first = #second) AND (#second = #third) THEN 1 ELSE 0 END
Following is one way to do it but after reading #meagar's comment, I find that solution to be more elegant. Just waiting for him to turn it into an answer...
DECLARE #firstcount INTEGER
DECLARE #secondcount INTEGER
DECLARE #thirdcount INTEGER
SET #firstcount = 1
SET #secondcount = 2
SET #thirdcount = 3
IF #firstcount <> #secondcount SELECT 0
ELSE IF #secondcount <> #thirdcount SELECT 0
ELSE SELECT 1
You are wanting to say If Firstcount is equal to second count, and secondcount is equal to third count return true.
You can just do
DECLARE #a INT = 2
DECLARE #b INT = 2
DECLARE #c INT = 2
IF (#a = #b AND #a = #c)
BEGIN
Print('true')
END
ELSE
BEGIN
Print('false')
END
Although it makes no difference you dont need to test B = C because A = C is exactly the same thing since all 3 values have to be the same.
Try the code ,
if ( (firstCount = secondCount) and (secondCount = thirdCount) and (firstCount = ThirdCount) )
return true;
else
return false;