I have 6 integer fields (called genre1 ... genre6 respectively). User enters selects from a drop down on the front end. What I would like to happen is messaging to appear stating that he's selected the same values for fields 1 and 2 or 1 and 3 etc.
It looks like this.
genre1 int,
genre2 int,
genre3 int,
genre4 int,
genre5 int,
genre6 int,
if genre1 = genre2
or genre1 = genre3
or genre1 = genre4
or genre1 = genre5
or genre1 = genre6
or genre2 = genre3
or genre2 = genre4
or genre2 = genre5
etc ...
I don't need to state the combination of fields that he's entered incorrectly only that he's done so and he should review the data before continuing.
This has to happen in a trigger (insert and update) on the table. There is other logic being tested and evaluated within the trigger as well but at the end I've added the following logic to start and it doesn't seem to work.
declare #genre1 int
set #genre1 = (select genre1 from lt_wmi_men_org_cs where id_key = #id_key)
-- select * from lt_wmi_men_org_cs
BEGIN TRY
IF (#genre1 = 6) -- This is used to test a particular value.
BEGIN
Select #genre1
END
END TRY
BEGIN CATCH
-- SELECT ERROR_MESSAGE() + #genre1 AS ErrorMessage;
DECLARE #ErrorNumber INT = ERROR_NUMBER();
DECLARE #ErrorLine INT = ERROR_LINE();
DECLARE #ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE();
DECLARE #ErrorSeverity INT = ERROR_SEVERITY();
DECLARE #ErrorState INT = ERROR_STATE();
PRINT ERROR_MESSAGE() + #genre1;
PRINT 'Actual error number: ' + CAST(#ErrorNumber AS VARCHAR(10));
PRINT 'Actual line number: ' + CAST(#ErrorLine AS VARCHAR(10));
END CATCH;
I've also tried a more complex if statement but none of it seems to be working.
BEGIN TRY
IF (#genre1 = #genre2 OR #genre1 = #genre3 OR #genre1 = #genre4 OR #genre1 = #genre5 OR #genre1 = #genre6 )
BEGIN
Select #genre1
END
END TRY
Please advise.
Thank you
Related
In my procedure i am returning a int value.
ALTER PROCEDURE [dbo].[GetValue]
-- Add the parameters for the stored procedure here
#ID int,
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
DECLARE #isNew int
SET #isNew=0
DECLARE #returnedValue int
DECLARE #output int
SET #returnedValue=[dbo].fn_GetIsNewLecturer(#ID)
IF(#returnedValue=0)
BEGIN
PRINT 'new'
EXEC #output=[dbo].[GetNew] #ID
SELECT #output
END
ELSE
BEGIN
PRINT 'old'
EXEC #output=[dbo].[sp_GetOld] #ID
SELECT #output
END
RETURN #output
END
it return value should be int. But it returns Nullable int?. how to change it as int
Try this:
select [Output] = isnull(#output, 0)
Here's why it should work:
declare #i int
select ni = #i, nni = isnull(#i,0)
into #t
select is_nullable, *
from tempdb.sys.columns
where [object_id] = object_id(N'tempdb..#t')
drop table #t
my problem is pretty simple. I get a value from a sql select which looks like this:
ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG
and I need it like this:
AR,AM,AU,BE,BA,BR,BG,CN,DK,DE,EE,FO,FI,FR,GE,GR,IE,IS,IT,JP,YU,CA,KZ,KG
The length is different in each dataset.
I tried it with format(), stuff() and so on but nothing brought me the result I need.
Thanks in advance
With a little help of a numbers table and for xml path.
-- Sample table
declare #T table
(
Value nvarchar(100)
)
-- Sample data
insert into #T values
('ARAMAU'),
('ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG')
declare #Len int
set #Len = 2;
select stuff(T2.X.value('.', 'nvarchar(max)'), 1, 1, '')
from #T as T1
cross apply (select ','+substring(T1.Value, 1+Number*#Len, #Len)
from Numbers
where Number >= 0 and
Number < len(T1.Value) / #Len
order by Number
for xml path(''), type) as T2(X)
Try on SE-Data
Time to update your resume.
create function DontDoThis (
#string varchar(max),
#count int
)
returns varchar(max)
as
begin
declare #result varchar(max) = ''
declare #token varchar(max) = ''
while DATALENGTH(#string) > 0
begin
select #token = left(#string, #count)
select #string = REPLACE(#string, #token, '')
select #result += #token + case when DATALENGTH(#string) = 0 then '' else ',' end
end
return #result
end
Call:
declare #test varchar(max) = 'ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG'
select dbo.DontDoThis(#test, 2)
gbn's comment is exactly right, if not very diplomatic :) TSQL is a poor language for string manipulation, but if you write a CLR function to do this then you will have the best of both worlds: .NET string functions called from pure TSQL.
I believe this is what QQping is looking for.
-- select .dbo.DelineateEachNth('ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG',2,',')
create function DelineateEachNth
(
#str varchar(max), -- Incoming String to parse
#length int, -- Length of desired segment
#delimiter varchar(100) -- Segment delimiter (comma, tab, line-feed, etc)
)
returns varchar(max)
AS
begin
declare #resultString varchar(max) = ''
-- only set delimiter(s) when lenght of string is longer than desired segment
if LEN(#str) > #length
begin
-- continue as long as there is a remaining string to parse
while len(#str) > 0
begin
-- as long as know we still need to create a segment...
if LEN(#str) > #length
begin
-- build result string from leftmost segment length
set #resultString = #resultString + left(#str, #length) + #delimiter
-- continually shorten result string by current segment
set #str = right(#str, len(#str) - #length)
end
-- as soon as the remaining string is segment length or less,
-- just use the remainder and empty the string to close the loop
else
begin
set #resultString = #resultString + #str
set #str = ''
end
end
end
-- if string is less than segment length, just pass it through
else
begin
set #resultString = #str
end
return #resultString
end
With a little help from Regex
select Wow=
(select case when MatchIndex %2 = 0 and MatchIndex!=0 then ',' + match else match end
from dbo.RegExMatches('[^\n]','ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG',1)
for xml path(''))
I am trying to insert data into a table based off what is already in the table. I read the table to get the number of records inserted for a certian month and then insert information based off if it is more or less than ten. After I read the table it throws an invalid object name when I try to do that insert. It's not an invalid object as it just read the table. If this is a permissions error how do I correct it? My code is below. Thanks,
Jason
declare #email VARCHAR(75),
#seminarNumber INT,
#isValidEmail BIT,
#monthlyTotal INT,
#statusCode INT
set #email = 'email#domain.com'
set #seminarNumber = '12345'
set #isValidEmail = dbo.RegexMatch('^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,3})|(aero|coop|info|museum|name))$',#email)
if #isValidEmail = 1
begin
SELECT #monthlyTotal = count(mailid)
from Email_Tracking
where emailaddress = #email
and year(datesent) = year(getdate())
and month(datesent) = month(getdate())
if #monthlyTotal > 10
begin
set #statusCode = 1
end
else
begin
set #statusCode = 2
end
end
else
begin
set #statusCode = 3
end
if #statusCode = 1
begin
insert Email_Tracking ('seminarNumber','email','reasonNotSent')
values(#seminarNumber,#email,'Maximum surveys for the month have already been sent')
end
else if #statusCode = 2
begin
insert Email_Tracking ('seminarNumber','email','datesent')
values(#seminarNumber,#email,getdate())
end
else if #statusCode = 3
begin
insertEmail_Tracking ('seminarNumber','email','reasonNotSent')
values(#seminarNumber,#email,'Email address missing or invalid')
end
print #statusCode
try removing quotes from column names. so for eg:
insert Email_Tracking (seminarNumber,email,reasonNotSent)
values(#seminarNumber,#email,'Email address missing or invalid')
I am trying to write a sproc with a transaction. Can anybody tell me if there would be any issues with code below, or if it will work as intended?
ALTER procedure [dbo].[DeleteMetricMeter]
(
#SectionID int,
#MetricMeterID int,
#Result bit output
)
as
declare #MetricMeterCount int
declare #err int
declare #rowcount int
set xact_abort on
begin tran
select #MetricMeterCount = count(*) from luMetricMeters
where fkSectionID = #SectionID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
delete from luMetricMeterList
where pkMetricMeterID = #MetricMeterID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
delete from luMetricMeters
where pkMetricMeterID = #MetricMeterID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
if (#MetricMeterCount = 1)
begin
delete from luMetricSections
where pkSectionID = #SectionID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
end
commit tran
set #result = 1
return #result
on_error:
rollback tran
set #result = 0
return #result
If you are using Sql Server 2005+, I would recomend rather using TRY...CATCH (Transact-SQL) and have a look at section [B. Using TRY…CATCH in a transaction]
This will GREATLY simplify your procedure.
There are a few issues with the procedure:
You should not evaluate rowcount unless it really indicates an error. When there is no data deleted there is no need to rollback.
Your code is not thread safe. The MetricMeterCount query should be changed to this to prevent other threads from performing the delete in between your select & the execution of the delete:
select #MetricMeterCount = count(*)
from luMetricMeters with (xlock, serializable)
where fkSectionID = #SectionID
I would write the code like this:
ALTER procedure [dbo].[DeleteMetricMeter]
(
#SectionID int,
#MetricMeterID int,
#Result bit output
)
as
DECLARE #MetricMeterCount int
DECLARE #err int
DECLARE #rowcount int
SET xact_abort ON
BEGIN TRAN
DELETE FROM luMetricMeterList
WHERE pkMetricMeterID = #MetricMeterID
SELECT #err = ##error
IF (#err <> 0)
GOTO on_error
DELETE FROM luMetricMeters
WHERE pkMetricMeterID = #MetricMeterID
SELECT #err = ##error
IF (#err <> 0)
GOTO on_error
IF EXISTS (SELECT *
FROM luMetricMeters WITH (xlock, serializable)
WHERE fkSectionID = #SectionID)
BEGIN
DELETE FROM luMetricSections
WHERE pkSectionID = #SectionID
SELECT #err = ##error
IF (#err <> 0)
GOTO on_error
END
COMMIT TRAN
RETURN (0)
on_error:
ROLLBACK TRAN
RETURN (-1)
GO
Note: The return values should be 0 for success and a negative number for failure.
I can:
declare #idOrder int
set #idOrder = 21319
I want:
declare #idOrder int
set #idOrder = (21319, 21320)
for use in a series of statements where the 'WHERE' clause uses the IN operator
delete Orders
where idOrder in #idOrder
instead of
delete Orders
where idOrder in (21319, 21320)
You can't do that as long as it's an int, as that's not a valid value for that datatype. A datatype that could take several integers is a table
declare #idOrder table (id int)
insert into #idOrder values(21319)
insert into #idOrder values(21320)
delete from Orders where idOrder in (select id from #idOrder)
In SQL Server you can also
CREATE FUNCTION [dbo].[fn_ado_param_int] (#ado nvarchar(4000))
RETURNS #VALUES TABLE (ado int)AS
BEGIN
declare #Delim char(1)
set #Delim = ','
DECLARE #chrind INT
DECLARE #Piece nvarchar(4000)
SELECT #chrind = 1
WHILE #chrind > 0
BEGIN
SELECT #chrind = CHARINDEX(#Delim,#ado)
IF #chrind > 0
SELECT #Piece = LEFT(#ado,#chrind - 1)
ELSE
SELECT #Piece = #ado
INSERT #VALUES(ado) VALUES(#Piece)
SELECT #ado = RIGHT(#ado,LEN(#ado) - #chrind)
IF LEN(#ado) = 0 BREAK
END
RETURN
END
declare #idOrder varchar(500);
set #inOrder = "21319,2138,2138";
delete from Orders where id in (select ado from dbo.fn_ado_param_int(#idOrder));