I've created an automated email that tells my customers when they've ordered a part that's on back order. It uses one SQL view and 2 stored procedures as listd below. My issue is that when I execute it, the first backorder sends an email with the title 'sql server message' and has no sql results in it. All subsequent backorders run properly with the correct subject and data in the body. Is there something I've done wrong in my sp's?
This sp runs first, and builds a list of our customers that have Backordered parts.
USE [001]
GO
/****** Object: StoredProcedure [mfg].[sp_BackorderEmailListing] Script Date: 6/29/2015 4:09:31 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Nicholas Dininno>
-- Create date: <6/15/15>
-- Description: <Runs through a distinct list of Franchisees that have
-- orders on backorder, and passes their info to [mfg].[sp_SendBackorderEmail]>
-- =============================================
ALTER PROCEDURE [mfg].[sp_BackorderEmailListing]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Declare #cmp_code nvarchar(50)
Declare #email nvarchar(Max)
Declare cur_BackOrdSP Cursor
For SELECT DISTINCT [Franchise ID] FROM [001].[mfg].[Backorder_Report]
Open cur_BackOrdSP
Fetch Next From cur_BackOrdSP
While ##FETCH_STATUS = 0
Begin
--find email address
SELECT #email = [cmp_e_mail] FROM [001].[mfg].[Backorder_Report] where [Franchise ID]=#cmp_code
execute [mfg].[sp_SendBackorderEmail] #cmp_code, #email
Fetch Next From cur_BackOrdSP Into #cmp_code
END
Close cur_BackOrdSP
Deallocate cur_BackOrdSP
END
The next part is where the email is built.
USE [001]
GO
/****** Object: StoredProcedure [mfg].[sp_SendBackorderEmail] Script Date: 6/29/2015 4:12:51 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Nick Dininno
-- Create date: 6/25/2015
-- Description: Sends email to Franchisees with backordered parts
-- =============================================
ALTER PROCEDURE [mfg].[sp_SendBackorderEmail]
-- Add the parameters for the stored procedure here
(#cmp_code nvarchar(5), #email nvarchar(50))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #profile nvarchar(50)
DECLARE #subject nvarchar(100)
DECLARE #querystr nvarchar (MAX)
set #profile = 'Reports'
set #subject = 'Backorder Report for ' + #cmp_code
set #querystr = 'SET NOCOUNT ON
SELECT [Order #],[Order Date],[Item #],[Description]
FROM [001].[mfg].[Backorder_Report]
WHERE [Franchise ID] = '''+#cmp_code+'''';
EXEC msdb.dbo.sp_send_dbmail
#profile_name = #profile,
#recipients = 'me#company.com',
#subject = #subject,
#body = 'Note: This is an automatic e-mail message generated by the Parts Department.
Our records indicate that you ordered the parts shown below. Unfortunately these parts are currently on backorder. They will be shipped to you as soon as they become available. In the meantime, if you have any questions or concerns regarding this order please contact the Parts Department via email parts#lawndoctor.com or call 732-308-2300 x4.
Thank you!
Parts Department
parts#company.com
',
#query = #querystr
END
The recipient me#company.com will be replaced once i'm sure it works with the #email parameter
My issue here was a syntax issue. In the first procedure I didn't pass the Franchise ID into #cmp_code.
Fetch Next From cur_BackOrdSP
Should have been
Fetch Next From cur_BackOrdSP into #cmp_code
Related
USE [ProjectDB]
GO
/****** Object: StoredProcedure [dbo].[generateTransRefNo] Script Date: 9/9/2017 7:19:55 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[generateTransRefNo]
(
#year varchar(max),
#txrefno varchar(max) output
)
AS
BEGIN
BEGIN TRANSACTION
SET NOCOUNT ON
DECLARE #seq varchar(max)
set #seq = '00000000'
select #txrefno = sequence from TBSEQUENCE WITH (TABLOCK, HOLDLOCK) where year =#year
if(#txrefno='' or #txrefno is null)
begin
insert into TBSEQUENCE values (substring(cast(DATEPART(year, GETDATE()) as varchar),3,4),1,'YR')
end
select #txrefno = concat(year,SUBSTRING('00000000',1,8- len(sequence)),sequence) from TBSEQUENCE where year =#year
update TBSEQUENCE set sequence = sequence+1 where year=#year
COMMIT TRANSACTION
END
select #txrefno
Say I have this stored procedure that gets the latest sequence from tbsequence then update it
The application is java using hibernate to access the database which is deployed already that I cannot access.
Will this hold the incoming requests while the current request is still up or cancel them and returns nothing?
I've got a trigger on a table. It's a very simple trigger, set to after insert, send me an e-mail. Since I've put that trigger on, I've been sent e-mails by the system every 5 or 6 minutes or so. There is just one problem.
Whenever I receive an e-mail, the table is EMPTY
Here is my trigger
USE [didaprod]
GO
/****** Object: Trigger [dbo].[Caseplayer_CaseId_Restore_insert_mail] Script Date: 09-08-2016 11:59:41 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE trigger [dbo].[Caseplayer_CaseId_Restore_insert_mail] on [dbo].[Caseplayer_CaseId_Restore]
AFTER INSERT
as
SET NOCOUNT ON
declare #tekst nvarchar(500);
set #tekst = 'caseid sat til null på caseplayer! Tjek Caseplayer_CaseId_Restore tabel!' + convert(varchar,getdate(),105);
EXEC msdb.dbo.sp_send_dbmail #profile_name = 'Mail',
#recipients = 'kk#byggeevaluering.dk',
#subject = 'CASEID SAT TIL NULL!!!',
#body = #tekst
SET NOCOUNT OFF
GO
I've tried to manually insert a row, or a couple of rows in the table, just to check, and yes, the trigger fires as well, when there is a proper insert. But I cannot explain why I keep receiving the e-mails!. As for the table itself, it's got nothing fancy.
USE [didaprod]
GO
/****** Object: Table [dbo].[Caseplayer_CaseId_Restore] Script Date: 09-08-2016 12:04:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Caseplayer_CaseId_Restore](
[Id] [int] NOT NULL,
[CaseId] [int] NOT NULL,
[TimeOfChange] [datetime] NOT NULL
) ON [PRIMARY]
GO
I've disabled the trigger now, and confirmed that the e-mails have stopped. But this seems like an almost magic problem for me, and I would love to get an answer.
Suppose I do
delete from [Caseplayer_CaseId_Restore]
And just leave the table alone.
I'll still get e-mails from the system, telling me to check the table. When I then perform a
select * from [Caseplayer_CaseId_Restore]
The table is empty
SQL Server triggers fire once per statement rather than once per row. That's why it's important to write triggers that use inserted appropriately, to deal with the fact that it may contain 1, many, or zero rows.
I suspect that it's the latter case here. (I.e. a regularly executed INSERT statement that is in fact inserting zero rows)
So, you might want something like:
CREATE trigger [dbo].[Caseplayer_CaseId_Restore_insert_mail]
on [dbo].[Caseplayer_CaseId_Restore]
AFTER INSERT
as
SET NOCOUNT ON
IF EXISTS(select * from inserted)
BEGIN
declare #tekst nvarchar(500);
set #tekst = 'caseid sat til null på caseplayer! Tjek Caseplayer_CaseId_Restore tabel!' + convert(varchar,getdate(),105);
EXEC msdb.dbo.sp_send_dbmail #profile_name = 'Mail',
#recipients = 'kk#byggeevaluering.dk',
#subject = 'CASEID SAT TIL NULL!!!',
#body = #tekst
END
my stored procedure :
USE [maskanjo.com_travelenterDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create PROCEDURE [dbo].[SPSelectCites]
-- Add the parameters for the stored procedure here
#cityName nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
--------------------------Select---------------------
CREATE VIEW CUSTOMERS_VIEW AS
SELECT *
FROM [dbo].[City] where [NameFA] LIKE cityName+'%'
-----------------------------------------------------
END
i want select city from cites table and create View
have error
Error :
Incorrect syntax:'CREATE VIEW' Must be only statement in the batch
The error tells you what the problem is. Try executing the query using the "Exec" command:
declare #sql varchar(max)
set #sql = 'CREATE VIEW CUSTOMERS_VIEW AS SELECT * FROM [dbo].[City]
where [NameFA] LIKE ''' + cityName + '%'''
exec (#sql)
I have created a service broker that stores id's in the queue table. But the problem is when i want to get the id back in the stored procedure it's now formatted as xml. Because the service broker message is XML.
How can i just get the last Id each time because the trigger is fired after an update of a row.
Below my code =>
/****** Object: Trigger [dba].[TriggerCall] Script Date: 6/16/2015 2:55:57 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dba].[TriggerCall] ON [dba].[CallID] FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #MessageBody XML
DECLARE #ID varchar(50)
-- Insert statements for trigger here
--get relevant information from inserted/deleted and convert to xml message
SET #MessageBody = (SELECT Id FROM inserted
FOR XML AUTO)
If (#MessageBody IS NOT NULL)
BEGIN
DECLARE #Handle UNIQUEIDENTIFIER;
BEGIN DIALOG CONVERSATION #Handle
FROM SERVICE [TestServiceInitiator]
TO SERVICE 'TestServiceTarget'
ON CONTRACT [TestContract]
WITH ENCRYPTION = OFF;
SEND ON CONVERSATION #Handle
MESSAGE TYPE [TestMessage](#MessageBody);
END
END
/****** Object: StoredProcedure [dbo].[usp_GetCall] Script Date: 6/16/2015 2:44:27 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_GetCall]
AS
BEGIN
DECLARE #message_type varchar(100)
DECLARE #dialog uniqueidentifier, #message_body XML;
Declare #Object as Int;
Declare #URL as varchar(255)
Declare #ResponseText as Varchar(8000);
Declare #ID as Varchar(38);
WHILE (1 = 1)
BEGIN -- Receive the next available message from the queue
WAITFOR (
RECEIVE TOP(1) #message_type = message_type_name,
#message_body = CAST(message_body AS XML),
#dialog = conversation_handle
FROM dbo.TestQueue ), TIMEOUT 500 if (##ROWCOUNT = 0 OR #message_body IS NULL)
BEGIN
BREAK
END
ELSE
BEGIN
INSERT INTO [dbo].[testtabel]
([id]
,[callid],
[test])
VALUES
('111', '111', #message_body)
END
END CONVERSATION #dialog
END
END
If I understand your question correctly, you're just looking to rehydrate the ID into an int. If that's the case, the following should do:
use tempdb;
create table inserted (id int);
insert into inserted values (1);
declare #message_body xml;
set #message_body= (select * from inserted for xml auto);
select #message_body.value('(/inserted/#id)[1]', 'int');
The magic is the last line (the rest was just setup for me to test).
I'll take this opportunity to clear up a misconception that you seem to have, though. Triggers in SQL server aren't fired per row, but per batch. So, if you run an update against your table and it updates 50 rows, the trigger gets fired once and the inserted (and deleted) table will have 50 rows in it. Just something to take into account.
I tried to achieve row level delete trigger by using cursor but when in trying yo delete the any row from table it tooks so long time.
I could not understand where exactly it stuck.
/****** Object: Trigger [delStudent] Script Date: 06/24/2010 12:33:33 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [delStudent]
ON [dbo].[Student]
FOR DELETE
AS
DECLARE #Roll as varChar(50);
DECLARE #Name as varChar(50);
DECLARE #Age as int;
DECLARE #UserName as varChar(50);
SELECT #UserName=SYSTEM_USER;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION;
declare CurD cursor for select roll, Sname, age from deleted
open CurD
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO [dbo].[Audit]
(roll,sname,age,userId)
VALUES
(#Roll,#Name,#Age,#UserName)
END
COMMIT TRANSACTION;
Close CurD
DEALLOCATE CurD
I think you should transform your cursor in an insert-select sentence. I'm not sure this will solve your problem, but it's a good best practice anyway.
INSERT [dbo].[Audit] (roll,sname,age,userId)
SELECT 'FIELDS FROM DELETED', SYSTEM_USER
FROM deleted
Try to avoid cursors, and this will result in better performance.