Default constraint to automatically change a value - sql

I have a table ProviderValueCard. Is it possible to set up a default constraint to when a new row is created, if column SessionsProgress is > 0 then automatically set the value of the entry for column SurveyCompleted = 1 and set it = 0 if SessionProgress = 0?
So psedo: If SessionsProgress > 0, then SurveyCompleted = 1 else SurveyCompleted = 0
I got the idea from marc_s answer on this question: Automatically inserting datetime with insert

Thanks to abatishchev, here's what worked. I couldn't figure out the > syntax error :/. I didn't have anything in that column that mattered yet, so dropping it wasn't an issue.
ALTER TABLE ProviderValueCard DROP COLUMN SurveyCompleted
ALTER TABLE ProviderValueCard ADD SurveyCompleted AS CASE [SessionsProgress] WHEN '1' THEN 1
WHEN '2' THEN 1
WHEN '3' THEN 1
WHEN '4' THEN 1
WHEN '5' THEN 1
WHEN '0' THEN 0
END

You get that behavior with bit
declare #bit bit;
set #bit = 0;
print #bit;
set #bit = 1;
print #bit;
set #bit = 2;
print #bit;
set #bit = 2000;
print #bit;

Related

Update one column only when any other column change

I am trying to create an update statement on SQL Server to set one of the cards as default and all the others as not, however, if I have 3 cards and card 1 set to default and now I want to set card 2 as default I get all 3 cards set as updated, when I should only set cards 1 and 2. I am currently using the following query:
UPDATE Card
SET
ModifiedDateTimeUtc = #ModifiedDateTimeUtc,
IsDefault = CASE WHEN Id = #CardId THEN 1 ELSE 0 END
WHERE CustomerId = #CustomerId;
I need to modify this query so only the cards with values updated get to set a new modified date/time.
PS, I cannot use triggers on this database (unfortunately) so I need to find a solution using a "simple" SQL statement.
Maybe it could be write in other ways but you can do like this:
UPDATE Card
SET
ModifiedDateTimeUtc =
CASE WHEN Id = #CardId THEN
CASE WHEN IsDefault = 1 THEN ModifiedDateTimeUtc ELSE #ModifiedDateTimeUtc END
ELSE
CASE WHEN IsDefault = 0 THEN ModifiedDateTimeUtc ELSE #ModifiedDateTimeUtc END
END,
IsDefault = CASE WHEN Id = #CardId THEN 1 ELSE 0 END
WHERE CustomerId = #CustomerId;
What should do this?
If the Id is the same with the parameter and the old value, before update, is 1, datetime will be the same, no update will be made, else (means old value = 0) then it will be updated. And the same for old value= 0...
Is this what you want?
UPDATE Card
SET ModifiedDateTimeUtc = #ModifiedDateTimeUtc,
IsDefault = (CASE WHEN Id = #CardId THEN 1 ELSE 0 END)
WHERE CustomerId = #CustomerId AND
IsDefault <> (CASE WHEN Id = #CardId THEN 1 ELSE 0 END);
Usually, I wouldn't repeat a CASE expression in the WHERE. In this case, though, this is the new value for the column, so I think it is a clean expression of the logic.

Update Set value 1 if value else set 0

I was just woking trough some old final exams as I stumbled across this task:
Table:
Create a single SQL query from this table which will check if Art_MWStSatz is 7% and set Art_Markierung to 1 if it is, else set Art_Markierung to 0.
I dont't have any idea on how to solve this. I asked my teacher by she didn't know an answer either.
Some translations:
Artikel = Item
MWSt Satz = vat rate
Markierung = mark
I don't have access to the solution so it all depends in your answers.
Use an UPDATE and a CASE. This assumes that '7%' is a string and not the int '7'
UPDATE table
SET
Art_Markierung = CASE
WHEN Art_MWStSatz = '7%'
THEN 1
ELSE 0
END;
I presume that 1 or 0 is true or false. In this situation, you can use a CASE like this:
UPDATE MyTable
SET Art_Markierung = CASE Art_MWStSatz
WHEN '7%' THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END
Assume Art_Markierung and Art_MWStSatz are integer:
UPDATE Artikel
SET Art_Markierung =
CASE
WHEN Art_MWStSatz = 7 THEN 1
ELSE 0
END

Algorithm for auto generated series number in sql

I want to make an algorithm for generate next series number by specified last series number in sql like below:
Last Number Next Number
> AAAA095 AAAA096
> AAAA999 AAAB001
> AAAB001 AAAB002
> AAAZ999 AABA001
After some try, Finally i got an algorithm & create it to SQL Scalar-valued function for this question as below
CREATE FUNCTION GetNextSeries ( #lastSeriesNo VARCHAR(8))
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE #nextSeriesNo VARCHAR(8)
DECLARE #CHAR1 CHAR=SUBSTRING(#lastSeriesNo,1,1)
DECLARE #CHAR2 CHAR=SUBSTRING(#lastSeriesNo,2,1)
DECLARE #CHAR3 CHAR=SUBSTRING(#lastSeriesNo,3,1)
DECLARE #CHAR4 CHAR=SUBSTRING(#lastSeriesNo,4,1)
DECLARE #n INT=SUBSTRING(#lastSeriesNo,5,3)
SET #n = #n + 1
IF(#n>999)
BEGIN
SET #n=1
IF(#CHAR4<>'Z')
BEGIN
SET #CHAR4=CHAR(UNICODE(#CHAR4)+1)
END
ELSE IF(#CHAR3<>'Z')
BEGIN
SET #CHAR4='A'
SET #CHAR3=CHAR(UNICODE(#CHAR3)+1)
END
ELSE IF(#CHAR2<>'Z')
BEGIN
SET #CHAR4='A'
SET #CHAR3='A'
SET #CHAR2=CHAR(UNICODE(#CHAR2)+1)
END
ELSE IF(#CHAR1<>'Z')
BEGIN
SET #CHAR4='A'
SET #CHAR3='A'
SET #CHAR2='A'
SET #CHAR1=CHAR(UNICODE(#CHAR1)+1)
END
END
SET #nextSeriesNo=#CHAR1+#CHAR2+#CHAR3+#CHAR4+(CASE LEN(#n) WHEN 1 THEN '00' WHEN 2 THEN '0' ELSE '' END)+convert(VARCHAR(3),#n)
RETURN #nextSeriesNo
END

SQL Server insert loop of strings

Thank you in advance for your help here.
I want to insert incremental numbers as strings to load some bulk test numbers into a db, here is what i'm using:
Declare
#Serialcounter bigint
set #Serialcounter = 0
while #Serialcounter < 10
insert into [TrackTrace].[dbo].[TAB_ELEMENT] ([Serial], [Batch], [Batch_Id], [QCSample], [StationID])
values(Convert(varchar(60), #Serialcounter), 'test', 8989, 0, 1)
set #Serialcounter = (#Serialcounter + 1)
but when I do this it does not increment the counter and I just insert duplicate numbers and do not stop. I think my problem is that my variable is incremented outside of the while loop, but I am not sure how to rectify this.
Declare
#Serialcounter bigint
set #Serialcounter = 0
while #Serialcounter < 10
BEGIN
PRINT #Serialcounter
--insert into [TrackTrace].[dbo].[TAB_ELEMENT]
--([Serial]
--,[Batch]
--,[Batch_Id]
--,[QCSample]
--,[StationID])
--Values(Convert(varchar(60),#Serialcounter),'test',8989,0,1)
set #Serialcounter = (#Serialcounter +1 )
END
You not giving begin and end so as for all loops only first statement is considered
I was missing BEGIN and END statements
DECLARE
#Serialcounter BIGINT
SET #Serialcounter = 0
WHILE #Serialcounter < 10
BEGIN -- here
INSERT INTO [TrackTrace].[dbo].[TAB_ELEMENT]
([Serial]
,[Batch]
,[Batch_Id]
,[QCSample]
,[StationID])
VALUES(Convert(varchar(60),#Serialcounter),'test',8989,0,1)
SET #Serialcounter = (#Serialcounter +1 )
END -- and here

SQL Server: Why does adding a null to a variable not cause an error?

I have a stored procedure that has a loop based on a counter. When the counter becomes NULL the loop ends without any error. Why doesn't SQL Server at least display a warning or error message like other programming languages?
Here is a code sample which exhibits the problem:
DECLARE #MasterCount int = 0;
DECLARE #Count int; -- initialized to NULL by SQL Server
PRINT 'Starting'
IF (#MasterCount IS NULL)
PRINT '#MasterCount IS NULL';
ELSE
PRINT '#MasterCount ' + CAST(#MasterCount AS varchar(10))
IF (#Count IS NULL)
PRINT '#Count IS NULL';
WHILE (#MasterCount IS NOT NULL)
BEGIN
SET #MasterCount += #Count;
IF ##ERROR <> 0 PRINT 'Error occured!'
PRINT 'Loop #Count ' + CAST(#Count AS varchar(10))
SET #Count -= 1;
END
IF ##ERROR <> 0 PRINT 'Error occured!'
IF (#MasterCount IS NULL)
PRINT '#MasterCount IS NULL';
ELSE
PRINT '#MasterCount ' + CAST(#MasterCount AS varchar(10))
PRINT 'Ending'
Produces the following output:
Starting
#MasterCount 0
#Count IS NULL
#MasterCount IS NULL
Ending
It doesn't raise an error because this is defined, documented behaviour.
If you have two apples and you know the weight of only one then it makes sense that the weight of both of them added together is not known.
You can actually get a warning to appear if you slightly alter the formulation.
Instead of
SET #MasterCount += #Count;
You could use
SELECT #MasterCount = SUM(C)
FROM (VALUES(#Count),
(#MasterCount )) V(C);
In which case it gives
Warning: Null value is eliminated by an aggregate or other SET
operation.
This does change the semantics however. As the null value was entirely ignored you would end up with #MasterCount simply being assigned back its original value rather than being set to null in your scenario.