I experienced an issue with the SQL Server service broker. If I quickly run several times a the script below.
BEGIN DIALOG CONVERSATION #DBHandle
FROM SERVICE A
TO SERVICE N'B'
ON CONTRACT CommandExec
WITH ENCRYPTION = OFF
Sometimes #DBHandle has value null. I noticed it because the SEND ON CONVERSATION fails with "The conversation handle is missing. Specify a conversation handle".
Are there any structural limits on SQL Server? I expected an error, why a null value is returned?
Thanks,
Dan
Related
I am newbie to SSIS. I am facing an issue executing sp_send_dbmail in one of my stored procedures which is being run by Execute SQL task in SSIS. Main problem is, it is not throwing any error and completing successfully even though profile with which I am running this SP doesn't exist. I suspect there is a configuration issue but I am not able to diagnose it.
I have found that SMTP is not configured on my staging server. Can it be the only reason? Even if it is, it should at least throw an error, but in logs I do not see any error messages for the same.
Also, if I am running this SP directly through SQL, I get "Profile doesn't exists" error. But when I am running same SP through SSIS (execute sql task), then it is executing successfully.
Any guidance on this issue can be a great help.
This is how I am calling sp_send_dbmail.
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Stagging Trigger',
#recipients = 'myemailID#test.com',
#subject = 'this is the SP to send mail from SP'
sp_send_dbmail only queues up the mail. Does not attempt to deliver, does not validate the email profile, cannot raise any of the errors you complain are missing.
Read here how to check the status of emails queued: Check the Status of E-Mail Messages Sent With Database Mail:
USE msdb ;
GO
-- Show the subject, the time that the mail item row was last
-- modified, and the log information.
-- Join sysmail_faileditems to sysmail_event_log
-- on the mailitem_id column.
-- In the WHERE clause list items where danw was in the recipients,
-- copy_recipients, or blind_copy_recipients.
-- These are the items that would have been sent
-- to danw.
SELECT items.subject,
items.last_mod_date
,l.description FROM dbo.sysmail_faileditems as items
INNER JOIN dbo.sysmail_event_log AS l
ON items.mailitem_id = l.mailitem_id
WHERE items.recipients LIKE '%danw%'
OR items.copy_recipients LIKE '%danw%'
OR items.blind_copy_recipients LIKE '%danw%'
GO
More articles on the topic:
Troubleshooting Database Mail Failures
Complete Troubleshooting Guide for SQL Server Database Mail
Your error is pretty clear in what is required. First off, create a profile and note down all the values that you will input on the wizard. This guide will help you create the profile correctly.
Once you have verified that the dbmail profile has been setup, its time to put it to test. If you cant send out email through the stored proc, I would want to talk to the AD admin or the person responsible for setting up the email server. This is to make sure that you can anonymously send emails and to take care of any potential relay server issues. Hope this helps.
I am learning how to use the Service Broker of SQL Server 2008 R2. When following the tutorial Completing a Conversation in a Single Database. Following the Lesson 1, I have successfully created the message types, contract, the queues and services. Following the Lesson 2, I have probably sent the message. However, when trying to receive the message, I get the NULL for the ReceivedRequestMsg instead of the sent content.
When looking at the sys.transmission_queue, the transmission_status for the message says:
An exception occurred while enqueueing a message in the target queue. Error: 15517, State: 1. Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.
I have installed SQL Server using the Windows login like Mycomp\Petr. I am using that login also for the lessons.
Can you guess what is the problem? What should I check and or set to make it working?
Edited 2012/07/16: For helping to reproduce the problem, here is what I did. Can you reproduce the error if you follow the next steps?
Firstly, I am using Windows 7 Enterprise SP1, and Microsoft SQL Server 2008 R2, Developer Edition, 64-bit (ver. 10.50.2500.0, Root Directory located at C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL).
Following the tutorial advice, I have downloaded the AdventureWorks2008R2_Data.mdf sample database, and copied it into C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL\DATA\AdventureWorks2008R2_Data.mdf
The SQL Server Management Studio had to be launched "As Administrator" to be able to attach the data later. Then I connected the SQL Server.
Right click on Databases, context menu Attach..., button Add..., pointed to AdventureWorks2008R2_Data.mdf + OK. Then selected the AdventureWorks2008R2_Log.ldf from the grid below (reported as Not found) and pressed the Remove... button. After pressing OK, the database was attached and the AdventureWorks2008R2_log.LDF was created automatically.
The following queries were used for looking at "Service Broker enabled/disabled", and for enabling (the Service Broker was enabled successfully for the database):
USE master;
GO
SELECT name, is_broker_enabled FROM sys.databases;
GO
ALTER DATABASE AdventureWorks2008R2
SET ENABLE_BROKER
WITH ROLLBACK IMMEDIATE;
GO
SELECT name, is_broker_enabled FROM sys.databases;
GO
Then, following the tutorial, the queries below were executed to create the message types, the contract, the queues, and the services:
USE AdventureWorks2008R2;
GO
CREATE MESSAGE TYPE
[//AWDB/1DBSample/RequestMessage]
VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE
[//AWDB/1DBSample/ReplyMessage]
VALIDATION = WELL_FORMED_XML;
GO
CREATE CONTRACT [//AWDB/1DBSample/SampleContract]
([//AWDB/1DBSample/RequestMessage]
SENT BY INITIATOR,
[//AWDB/1DBSample/ReplyMessage]
SENT BY TARGET
);
GO
CREATE QUEUE TargetQueue1DB;
CREATE SERVICE
[//AWDB/1DBSample/TargetService]
ON QUEUE TargetQueue1DB
([//AWDB/1DBSample/SampleContract]);
GO
CREATE QUEUE InitiatorQueue1DB;
CREATE SERVICE
[//AWDB/1DBSample/InitiatorService]
ON QUEUE InitiatorQueue1DB;
GO
So far, so good.
Then the following queries are used to look at the queues (now empty when used):
USE AdventureWorks2008R2;
GO
SELECT * FROM InitiatorQueue1DB WITH (NOLOCK);
SELECT * FROM TargetQueue1DB WITH (NOLOCK);
SELECT * FROM sys.transmission_queue;
GO
The problem manifests when the message is sent:
BEGIN TRANSACTION;
BEGIN DIALOG #InitDlgHandle
FROM SERVICE
[//AWDB/1DBSample/InitiatorService]
TO SERVICE
N'//AWDB/1DBSample/TargetService'
ON CONTRACT
[//AWDB/1DBSample/SampleContract]
WITH
ENCRYPTION = OFF;
SELECT #RequestMsg =
N'<RequestMsg>Message for Target service.</RequestMsg>';
SEND ON CONVERSATION #InitDlgHandle
MESSAGE TYPE
[//AWDB/1DBSample/RequestMessage]
(#RequestMsg);
SELECT #RequestMsg AS SentRequestMsg;
COMMIT TRANSACTION;
GO
When looking at the queues, the Initiator... and the Target... queues are empty, and the sent message can be found in sys.transmission_queue with the above mentioned error reported via the transmission_status.
alter authorization on database::[<your_SSB_DB>] to [sa];
The EXECUTE AS infrastructure requires dbo to map to a valid login. Service Broker uses the EXECUTE AS infrastructure to deliver the messages. A typical scenario that runs into this problem is a corporate laptop when working from home. You log in to the laptop using cached credentials, and you log in into the SQL using the same Windows cached credentials. You issue a CREATE DATABASE and the dbo gets mapped to your corporate domain account. However, the EXECUTE AS infrastructre cannot use the Windows cached accounts, it requires direct connectivity to the Active Directory. The maddening part is that things work fine the next day at office (your laptop is again in the corp network and can access to AD...). You go home in the evening, continue with Lesson 3... and all of the sudden it doesn't work anymore. Make the whole thing seem flimsy and unreliable. Is just the fact that AD conectivity is needed...
Another scenatio that leads to the same problem is caused by the fact that databases reteint the SID of their creator (the Windows login that issues the CREATE DATABASE) when restored or attached. If you used a local account PC1\Fred when you create the DB and then copy/attach the database to PC2, the account is invalid on PC2 (it is scoped to PC1, of course). Again, not much is affected but EXECUTE AS is, and this causes Service Broker to give the error you see.
And last example is when the DB is created by a user that later leaves the company and the AD account gets deleted. Seems like revenge from his part, but he's innocent. The production DB just stops working, simply because it's his SID that the dbo maps too. Fun...
By simply changing the dbo to sa login you fix this whole EXECUTE AS thing and all the moving parts that depend on it (and SSB is probably the biggest dependency) start working.
You would need to grant receive on your target queue to your login. And it should work!
USE [YourDatabase]
GRANT RECEIVE ON [dbo].[YourTargetQueue]
TO [Mycomp\Petr];
GO
And you also need to grant send for your user, permission on Target Service should be sufficient, but let's enable on both services for the future.
USE AdventureWorks2008R2 ;
GO
GRANT SEND ON SERVICE::[//AWDB/1DBSample/InitiatorService]
TO [Mycomp\Petr] ;
GO
GRANT SEND ON SERVICE::[//AWDB/1DBSample/TargetService]
TO [Mycomp\Petr] ;
GO
I have a bunch of stored procs doing the business logic job in a SQL Server instance within a web application. When something goes wrong all of them queue a message in a specific table (let's say 'warnings') keeping track of the error severity and issue description. I want the web application using the stored procs to be able to query the message table at the end of the run but getting a list of the proper message only, i.e. the message created during the specific session or that specific connection: so I am in doubt if
have the web application send to the db a guid to INSERT as column value in the message records (but somehow I have to keep track of it in several stored procs running at the page level, so I need something "global")
OR
if I can use some id related to the connection opened by the application - and this would be definitely more sane. Something like (this is pseudo code):
SELECT #sessionid = sessionid FROM sys.something where this = that
Have some hints?
Thanks a lot for your ideas
To retrieve your current SessionId in SQL Server you can simply execute the following:
select ##SPID
See:
http://msdn.microsoft.com/en-us/library/ms189535.aspx
Can I ask what is the difference between xp_sendmail and sp_send_dbmail proc? They are both send e-mail message, which may include a query result set attachment, to the specified recipients.....
What is the difference?
xp_sendmail requires a MAPI client installed, such as Outlook, on the server. This is the only option for SQL Server 2000 and before.
sp_send_dbmail is a simple SMTP solution, added for SQL Server 2005+
sp_send_dbmail is by far better.
Another difference between the two is that email message sent using sp_send_dbmail() will be rolled back (not sent) if the transaction is rolled back. This does not happen with email sent using xp_sendmail().
So, if you want the email message to be sent regardless of the end result of the transaction you'll need to use xp_sendmail().
I was sending emails to notify users if an SP was unable to complete it's processing. Of course, I was rolling back the transaction in that event. When I switched to sp_send_dbmail() the transactions that were being rolled back (the very ones I wanted to get an email notification from) stopped sending emails.
we don't control the calling code - it's closed and calls the sp in a transaction. We need a feature in SQL Server to send direct or flush the mail queue.
We are trying to make conversation between two SQL instances in one SQL Engine through Service Broker by following tutorial from MSDN.
In order to make it simple , we send the dialog with Encryption = OFF so we do not need to deal with Master key , Certificate... and it works in the local workstation.
DECLARE #InitDlgHandle UNIQUEIDENTIFIER;
DECLARE #RequestMsg NVARCHAR(100);
BEGIN TRANSACTION;
BEGIN DIALOG #InitDlgHandle
FROM SERVICE [//InstDB/2InstSample/InitiatorService]
TO SERVICE N'//TgtDB/2InstSample/TargetService'
ON CONTRACT [//BothDB/2InstSample/SimpleContract]
WITH
ENCRYPTION = OFF;
SELECT #RequestMsg = N'Message for Target service.';
SEND ON CONVERSATION #InitDlgHandle
MESSAGE TYPE [//BothDB/2InstSample/RequestMessage]
(#RequestMsg);
SELECT #RequestMsg AS SentRequestMsg;
COMMIT TRANSACTION;
GO
However , After moving to the server , With the same script, the target DB keep showing "Can not found private key , message can not deliver" in the SQL trace after initDB send out the message.
My question is since we set the encryption = OFF , why the target DB shows missing certificate ?
We use SQL 2005 SP2 , Windows 2003
Appreciated for any input.
Talking about coming late to the party...
Didn't seen this post before. I don't know if is still of any relevance, but here's the probably cause:
The REMOTE SERVICE BINDING presence will trump the ENCRYPTION = OFF. This is to allow separation of developer duties from administrator duties. If Encryption is required by the Application, then the developer specifies ENCRYPTION = ON and the administrator must provide a REMOTE SERVICE BINDING. If the Application does not require encryption, then the developer specifies ENCRYPTION = OFF and the administrator may provide a REMOTE SERVICE BINDING if the deployment site decides that the encryption is needed, even if the application does not require it.
A full description of how dialog security and authentication works can be found on my site.