INSERT query from trigger inserts NULL - tsql

I have the following query in SQL Server 2005:
DECLARE #issueid numeric(10,0)
DECLARE #domain nvarchar (255)
SET #issueid = (SELECT issueid FROM issues WHERE issueid = 4850)
SET #domain = (SELECT fielddata FROM customfielddata WHERE issueid = #issueid AND customfieldid = 99)
PRINT CONVERT(NVARCHAR, #issueid) + ': ' + #domain
It outputs the result as expected:
4850: www.domain.com
When I have the same query in a trigger, it inserts the #issueid value correctly in the first column, but NULL in place of #section_name in the 2nd column:
CREATE TRIGGER trigger_website_sections
ON gemini_issues
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
IF (SELECT issuetypeid FROM inserted) = 58 BEGIN
DECLARE #issueid numeric(10,0)
DECLARE #domain nvarchar (255)
SET #issueid = (SELECT issueid FROM inserted)
SET #domain = (SELECT fielddata FROM customfielddata WHERE issueid = #issueid AND customfieldid = 99)
INSERT INTO website_sections VALUES (#issueid, #domain);
END
END
Can someone help figure out why?

Ok, after some more work I realised that because the row in customfielddata is created only after a row is created in issues (the 2nd is the primary table, and the 1st stores supplementary data for created records), the query on customfielddata will return NULL.
And trying to concatenate a string with a NULL returns a NULL and that's what's inserted into the row.
Mystery solved.

Related

Could not get desired column names using MDX in SQL Openquery. Need MEMBERs instead of complete hierarchy in columns name

Below is the TSQL I have written to fetch execute MDX using Openquery. However, I am unable to get columns in required format. Need columns title as Member only and Total column at the end of the table
DECLARE #DateFrom varchar(100)
SET #DateFrom = '2022-03-01'
DECLARE #DateTo varchar(100)
SET #DateTo = '2022-03-30'
DECLARE #Measure varchar(100)
SET #Measure = '[Measures].[Total Items]';
SET #sql = 'SELECT *
FROM OPENQUERY(POSCUBE,''
SELECT
(
[Date].[FirstDateOfWeek].Members,
{
'+#Measure+'
}
)
ON COLUMNS,
ORDER
(
(
[Product].[ProductName].Children,
[Product].[BrandName].Children
)
,
[Measures].[Total Items]
,
BDESC
)
ON ROWS
FROM [Model]
WHERE
([Date].[Date].['+#DateFrom+'] : [Date].[Date].['+#DateTo+']
) '')'
PRINT (#sql)
EXEC (#sql)
This is giving me below result
Current Result
I need result something like this where ALL (Row Total is at the end and Column Titles are Members value)
Required Result

SQL Server During Merge can i store source table value into variable

See my code to understand what i am trying.
DECLARE #LI NVARCHAR(100)
DECLARE #XFundCode VARCHAR(20)
SET #LI = ''
MERGE INTO TblLineItemTemplate Trg
USING
(
SELECT MAX(Section) AS Section,
MAX(LineItem) AS LineItem,
MAX(XFundCode) AS XFundCode,
MAX(StandardDate) AS StandardDate,
MAX(StandardValue) AS StandardValue,
MAX(ActualProvidedByCompany) AS ActualProvidedByCompany,
MAX(TickerID) AS TickerID
FROM #TmpTenQKData
GROUP BY LineItem
) AS Src
ON UPPER(TRIM(Trg.LineItem)) = UPPER(TRIM(Src.LineItem)) AND Trg.TickerID = Src.TickerID
WHEN MATCHED THEN
UPDATE SET
XFundCode = Src.XFundCode,
Action = 'U',
Insertdate = GETDATE()
WHEN NOT MATCHED THEN
SET #LI=Src.LineItem
SET #XFundCode = Src.XFundCode
INSERT
(
TickerID,
LineItem,
XFundCode,
Action,
UserID,
Insertdate
)
VALUES
(
TRIM(#TickerID),
TRIM(#LI),
TRIM(#XFundCode),
'I', #UserID,
GETDATE()
);
i want to store this way without OUTPUT clause
SET #LI=Src.LineItem
SET #XFundCode = Src.XFundCode
is it possible ?
please tell me a way to store source table value into variable during
insert/update from merge statement.
for each insert how can i store source table value by output clause. thanks

How to fill column basing on two other columns

I have table LessonHour with empty Number column.
TABLE [dbo].[LessonHour]
(
[Id] [uniqueidentifier] NOT NULL,
[StartTime] [time](7) NOT NULL,
[EndTime] [time](7) NOT NULL,
[SchoolId] [uniqueidentifier] NOT NULL,
[Number] [int] NULL
)
How can I fill up the table with Number for each LessonHour so it would be the number of lesson hour in order?
The LessonHours cannot cross each other. Every school has defined its own lesson hour schema.
Example set of data
http://pastebin.com/efWCtUbv
What'd I do:
Order by SchoolId and StartTime
Use Cursor to insert into row next number, starting from 1 every time the SchoolId changes.
Edit:
Solution with cursor
select -- top 20
LH.[Id],
[StartTime],
[EndTime],
[SchoolId]
into #LH
from
LessonHour as LH
join RowStatus as RS on LH.RowStatusId = RS.Id
where
RS.IsActive = 1
select * from #LH order by SchoolId, StartTime
declare #id uniqueidentifier, #st time(7), #et time(7), #sid uniqueidentifier
declare #prev_sid uniqueidentifier = NEWID()
declare #i int = 1
declare cur scroll cursor for
select * from #LH order by SchoolId, StartTime
open cur;
fetch next from cur into #id, #st, #et, #sid
while ##FETCH_STATUS = 0
begin
--print #prev_sid
if #sid <> #prev_sid
begin
set #i = 1
end
update LessonHour set Number = #i where Id = #id
print #i
set #i = #i + 1
set #prev_sid = #sid
fetch next from cur into #id, #st, #et, #sid
end;
close cur;
deallocate cur;
drop table #LH
This is the result I was after http://pastebin.com/iZ8cnA6w
Merging the information from the StackOverflow questions SQL Update with row_number() and
How do I use ROW_NUMBER()?:
with cte as (
select number, ROW_NUMBER() OVER(partition by schoolid order by starttime asc) as r from lessonhour
)
update cte
set number = r
Would this work
CREATE TABLE [dbo].[LessonHour]
(
[Id] [uniqueidentifier] NOT NULL,
[StartTime] [time](7) NOT NULL,
[EndTime] [time](7) NOT NULL,
[SchoolId] [uniqueidentifier] NOT NULL,
[Number] AS DATEDIFF(hour,[StartTime],[EndTime])
)
So if I understand the question correctly you require a calculated column which takes in the values of [StartTime] and [EndTime] and returns the number of hours for that lesson as an int. The above table definition should do the trick.

How Coalesce works in sql server?

Create table test(Names varchar(100) primary key )
insert into test values('Hugeman')
insert into test values('Jack')
insert into test values('William')
insert into test values('Kevin')
insert into test values('Peter')
Query 1:
declare #sql varchar(100)
select #sql = coalesce(#sql+'+','')+Names from test order by names-- where object_id =object_id('temp')
print #sql
This will result as
Hugeman+Jack+Kevin+Peter+William
Query 2
declare #sql varchar(100)
select #sql = coalesce(Names+'+','') from test order by names-- where object_id =object_id('temp')
print #sql
This will results William+
As per the documentation of coalesce, will return the first not null value. So it has to result Hugeman+. But it returns the entire rows.
Why query2 haven't done the same ?
This is not stricly connected to COALESCE.
Try these SELECTs:
DECLARE #sql1 AS VARCHAR(1000)
SELECT #sql1 = ISNULL(#sql1, '') + Names FROM test ORDER BY Names
PRINT #sql1
DECLARE #sql2 AS VARCHAR(1000)
SELECT #sql2 = Names FROM test ORDER BY Names
PRINT #sql2
So what happened? For EACH record selected:
in query 1 you keep adding values to #sql
in query 2 you reset #sql as the last name extracted
I don't understand exactly what you want to obtain from your SELECT, but a better example of COALESCE could be:
CREATE TABLE TEST2(Name VARCHAR(100) PRIMARY KEY, Telephone VARCHAR(10), Mobile VARCHAR(10))
INSERT INTO TEST2 VALUES('Hugeman', 1, 2)
INSERT INTO TEST2 VALUES('Jack', NULL, 3)
INSERT INTO TEST2 VALUES('William', 4, NULL)
INSERT INTO TEST2 VALUES('Kevin', 5, 6)
INSERT INTO TEST2 VALUES('Peter', NULL, NULL)
SELECT Name,
COALESCE(Telephone, Mobile) AS Tel
FROM TEST2
#sql is on the right hand side on the first to get appended
On the last #sql is all alone on the left side and has the value of the last row
Query-1: Appending the values of all rows to #sql
Query-2: Re-setting values to #sql
The below is the rows with order by names
Hugeman
Jack
Kevin
Peter
William
Query-1 Appends all values to #sql.
Query-2 Re-writing values to #sql, so the last row in the list is William so when you print the variable the last re-assigned value is printed.
The COALESCE() function returns the first non null value from the from the columns as parameters in COALESCE() function.
e.g.
SELECTCOALESCE(null,null,1,2) ///return --1
SELECT Id, COALESCE(FirstName, MiddleName, LastName) AS Name
FROM tblEmployee //return 1st non null value from FirstName/MiddleName/LastName

Create a stored procedure with parametes that Returns a value

I am trying to create a stored procedure that returns the ID of a user when the user firstname is entered correctly. Based on the returned ID I would like my IF condiction to return a unqiue number to tell me if user exists in database. I hope that makes sense. Thanks.
ALTER PROC dbo.PassParamUserID
#UserID int
AS
DECLARE #FirstName varchar(50)
set nocount on
SELECT f_Name
FROM tb_User
WHERE tb_User.f_Name = #FirstName;
BEGIN
IF #UserID is not null
RETURN 222
ELSE
RETURN 333;
SET NOCOUNT OFF;
END
If I understand you correctly, you are checking if the firstname exists in the table, and if it does, return the id for that firstname.. if it does not exist, then you want the procedure to return a code that tells you that the ID is missing
In that case, you want #FirstName coming in as a parameter and the #UserId variable gets selected from a matching row in the database
ALTER PROC dbo.PassParamUserID
#FirstName varchar(50)
AS
set nocount on
DECLARE #UserId INT
SELECT #UserID = UserId
FROM tb_User
WHERE tb_User.f_Name = #FirstName
IF #UserID IS NULL
BEGIN
SET #UserId = -999
END
SELECT #UserId
GO
It may be a better idea to check for matches involving both first and last name. Also, what do you do if the name exists multiple times? Use SET ROWCOUNT 1 to take care of this
ALTER PROC dbo.PassParamUserID
#FirstName varchar(50),
#LastName varchar(50)
AS
set nocount on
DECLARE #UserId INT
SET ROWCOUNT 1
SELECT #UserID = UserId
FROM tb_User
WHERE tb_User.f_Name = #FirstName
AND tb_User.l_Name = #LastName
SET ROWCOUNT 0
IF #UserID IS NULL
BEGIN
SET #UserId = -999
END
SELECT #UserId
GO
Using a bit out parameter
create procedure GetUserExists
#FirstName varchar(50),
#Ret bit out
as
if exists(select *
from tb_User
where tb_User.FirstName = #FirstName)
set #Ret = 1
else
set #Ret = 0
If I understood you correctly, this select query may work:
SELECT CASE WHEN EXISTS ( SELECT
TOP 1 1
FROM tb_User WHERE tb_User.f_Name = #FirstName ) THEN
1 ELSE 0 END
It will return a 1 if the user exists, 0 otherwise. It should perform more optimally because the use of top 1 (i.e. no need to scan for the existence of more than 1 row).