显示标签为“service”的博文。显示所有博文
显示标签为“service”的博文。显示所有博文

2012年3月29日星期四

flow of events while sending message from one serivce two another

Hello,

I want to know the exact flow of events when I use this statement:

BEGIN DIALOG CONVERSATION @.dialog_handle
FROM SERVICE [SERVICE1]
TO SERVICE 'SERVICE2'
ON CONTRACT [MainContract]

Assuming that I have defined SERVICE1 for Queue1 in the initiator ,

and I have defined SERVICE2 for queue2 on the target.

Is this the flow:

1.Message first goes to the queue1
or
it directly goes to the SERVICE2 on target end point which in turn puts this message in Queue2 on the target?

2. target queue then activates the stored procedure which is connected to queue2 (let's say the procedure name is 'Processqueue2')

3.I noticed that even when none of the item comes in the queue, still when u use "ALTER QUEUE queue2 WITH STATUS = ON", that time also the 'processqueue2' is called.

4.'processqueue2' then fetch message from queue2 and process this. optionally it can send the acknowledgement message to the initiator or just send the end dialog message.

5.if i dont want 'processqueue2' to send the acknowledgement then
can I can directly send the End dialog from the inititor it self i.e. the end dialog just after sending the message.


BEGIN DIALOG CONVERSATION @.dialog_handle
FROM SERVICE [SERVICE1]
TO SERVICE 'SERVICE2'
ON CONTRACT [MainContract]

SEND ON CONVERSATION @.dialog_handle
MESSAGE TYPE SendMessageType ('hello from intiator')

END CONVERSATION @.dialog

In this case why do i need queue1 at all?

my assumption here is that my communication is one way and i don't need the ACK from the target.

Thanks,

BEGIN DIALOG alone does not actualy send any message. It just create the initiator endpoint in sys.conversation_endpoints.

When you SEND a message, the message goes at first into sys.transmission_queue. After the SEND is commited, the message is picked up from sys.transmission_queue and delivered to he machines where SERVICE2 is hosted and is enqueued into Queue2. After the enqueue into Queue2 is commited, an ACK is automatically sent back to the host of SERVICE1 and this allows the message to be deleted from sys.transmission_queue.
In the case when SERVICE1 and SERVICE2 are within the same SQL Server instance, we might try to optimize the SEND by directly enqueueing the message into Queue2 (skip the intermediate step of sys.transmission_queue). If this optimization attempt fails for whatever reason (e.g. Queue2 is diasbled), then the normal path of sys.transmission_queue is used even within the same SQL instance (in fcat, even within the same database).

You application cannot send ACK replies, it can only send real message replies. These are ordinary messages sent from target to initiator, and they would follow the exact sequence as above.

Procedure activation (Processqueue2) happens whenever there are available (i.e. unlocked) messages in the queue. It is not a trigger, the procedure does not get activated once for each message. The algorithm that determines when to activate a new instance of the procedure (up to the max of MAX_QUEUE_READERS setting) monitors the activity of the procedure (RECEIVE statements) vs. the incomming rate of messages and determines when the procedure cannot keep up and launches a new instance of it. When you enable a queue, if there are messages in the queue, it will activate the procedure. Same goes for server start-up, database going online etc (if there are messages in the queue, it will activate the procedure).
It is not guaranteed that the activated procedure will actually find messages in the queue. The code of the procedure should always be prepared with being activated but finding the queue empty (altough we do try hard not to activate in such situations).

A one way message flow that does BEGIN DIALOG/SEND/END is at risk of running into problems if the target service suddenly starts erroring dialogs (e.g. permissions change, or service contract changes etc). Because the initiator has already ended the conversation, when the error comes back from the target it will be droped. The initiator has no way of evem knowing the error occured. A much better message exchange patttern is to BEGIN DIALOG/SEND from the initiator, RECEIVE/END from the target, then RECEIVE/END from the initiator (i.e. the target ENDs first). The initiator does not have to sit there waiting for the target to reply, the EndDialog message sent tby the target can be processed by a procedure attached to queue1. This issue is also discussed in this thread: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=273523&SiteID=1.

HTH,
~ Remus

sql

Floating Point Exception in SQL Server 2000

Hi,

I got below error in the SQL Server Production Server and i checked in the microsoft site it needs to install SQL Server service pack 4 to resolve the
problem.

"A floating point exception occurred in the user process. Current transaction is canceled"

I need help that i want to reproduce this below problem in the SQL Server environment and tried several ways but no luck.

Please advise me how to reproduce the problem.

Would be appreciate your help.

Regards
SathishFor what cause you are trying to do that? Check this ...Link (http://www.dbforums.com/showthread.php?t=318196)|||Wants to check after installing service pack 4. so that we can confirm it should not happen in future.
Any clues to reprodue it.

Regards
Sathish|||Wants to check after installing service pack 4. so that we can confirm it should not happen in future.
Any clues to reprodue it.

Regards
Sathish
FYI...
If the following conditions are all true, Microsoft SQL Server may store floating point data with an exponent lower than -308, which may cause floating point underflow exceptions that terminate a clients connection to SQL Server:

• The client application is using stored procedures or server side cursors to perform data modification
and passes the request to the SQL Server server as a remote procedure call (RPC) event.
• The client application is passing parameters for the RPC event to the SQL Server server.
• The column of the table affected by the parameter that is passed is defined as a float datatype.
• If a stored procedure is called, the parameter is defined as a float datatype.

And plz check the previous link that I gave you...You could get you answer there.|||Joydeep,

Thanks for your information. I have tried following ways to reproduce it

1. By using Index Tuning Wizard Execution
2. By passing the expression 0/0 (zero divided by zero) to SQL Server as a floating point value for a stored procedure parameter
3. By trying query with aggregate function
4. By running a Complex Query
5. By Query optimization

But i couldnt able to reproduce it. Do you have any stored procedure or SQL Query to stimulate this problem.

Regards
Sathishsql

2012年3月21日星期三

Flag -T1118, "Concurrency enhancements for the tempdb database", is it required with SQL 2

Hi:
Is the flag -T1118 required to solve the problem described in
http://support.microsoft.com/kb/328551, when you have SQL Server 2000 with
Service Pack 4, or it's unecessary?
I'm not sure if this is unecessary. I didn't see, anywhere, something
like "Hey, man, apply SP4, create multiple files for tempdb, and forget
the -T1118 flag, it's not required anymore...". The documentation says, in a
shy way, that's the problem is solved on SP4, but I've found places that
says to always create multiple files for tempdb.
What's the correct? Should I always have -T1118 applied or it's not
required?
TIA,
--
Ravi Wallau
nospam@.nospam.orgYou might want to do a feedback on that KB asking for clarification. Here's what is going on:
Trace flag 1118 will mean no allocations from mixed extents (except from IAM pages). This can
increase concurrency on your tempdb as it will decrease hit on the SGAM page.
The fix in the KB mean that several files for tempdb will be used in a round-robin fashion,
essentially spreading out SGAM hit over several files.
You can combine one with the other. Since eliminating mixed extents for data will mean increased
storage utilization, I recommend you go for the KB fix to start with. If you still feel you have
resource contention of the tempdb SGAM page, try adding trace flag 1118 as well.
We recently had a discussion in the MVP group on how the article is worded, but I have a feeling
that the discussion didn't trigger a re-wording in the article...
--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
"Ravi Ambros Wallau" <nospam@.nospam.com> wrote in message
news:OykXgqtRGHA.5900@.tk2msftngp13.phx.gbl...
> Hi:
> Is the flag -T1118 required to solve the problem described in
> http://support.microsoft.com/kb/328551, when you have SQL Server 2000 with Service Pack 4, or it's
> unecessary?
> I'm not sure if this is unecessary. I didn't see, anywhere, something like "Hey, man, apply
> SP4, create multiple files for tempdb, and forget the -T1118 flag, it's not required anymore...".
> The documentation says, in a shy way, that's the problem is solved on SP4, but I've found places
> that says to always create multiple files for tempdb.
> What's the correct? Should I always have -T1118 applied or it's not required?
> TIA,
> --
> Ravi Wallau
> nospam@.nospam.org
>sql

2012年3月19日星期一

FK Constraint

Hi,
My Master table structure
CREATE TABLE [dbo].[GR_CHANNEL_M] (
[CHANNELNO] [varchar] (50) NOT NULL ,
[SERVICE] [varchar] (50) NOT NULL ,
[IVR] [varchar] (50) NOT NULL CONSTRAINT [GR_CHANNEL_M_PK] PRIMARY KEY
CLUSTERED ([IVR],[CHANNELNO]),
[OPTIONAL1] [varchar] (50) NULL ,
[OPTIONAL2] [varchar] (50) NULL )
GO
My transaction table
CREATE TABLE [dbo].[GR_CALL_DETAILS_M] (
[CALLID] [varchar] (50) NOT NULL constraint GR_CALL_DETAILS_M_PK primary
key clustered(CALLID),
[DATEANDTIME] [datetime] NULL ,
[DURATION] [numeric](10, 0) NULL ,
[IVR] [varchar] (50) NOT NULL ,
[CHANNELNO] [varchar] (50) NOT NULL CONSTRAINT
[CHANNEL_M_SCHEMECHANGE_T_FK1] FOREIGN KEY ([CHANNELNO])
REFERENCES [dbo].[GR_CHANNEL_M] ([CHANNELNO]),
[CALLTERMINATE] [varchar] (50) NULL)
If I create the table GR_CALL_DETAILS_M i am getting the error
There are no primary or candidate keys in the referenced table
'dbo.GR_CHANNEL_M' that match the referencing column list in the foreign key
'CHANNEL_M_SCHEMECHANGE_T_FK1'.
How to solve this?
thanks
vanithaYour foreign key is not linked to a primary key or unique constraint. For
example, if the primary key of gr_channel_m were channelno,
gr_call_details_m would work just fine.
Ben Nevarez
"vanitha" <vanitha@.discussions.microsoft.com> wrote in message
news:8B38AC26-7E65-4CCD-BBFA-BBB8BDF5A0AA@.microsoft.com...
> Hi,
> My Master table structure
> CREATE TABLE [dbo].[GR_CHANNEL_M] (
> [CHANNELNO] [varchar] (50) NOT NULL ,
> [SERVICE] [varchar] (50) NOT NULL ,
> [IVR] [varchar] (50) NOT NULL CONSTRAINT [GR_CHANNEL_M_PK] PRIMARY KEY
> CLUSTERED ([IVR],[CHANNELNO]),
> [OPTIONAL1] [varchar] (50) NULL ,
> [OPTIONAL2] [varchar] (50) NULL )
> GO
> My transaction table
> CREATE TABLE [dbo].[GR_CALL_DETAILS_M] (
> [CALLID] [varchar] (50) NOT NULL constraint GR_CALL_DETAILS_M_PK primary
> key clustered(CALLID),
> [DATEANDTIME] [datetime] NULL ,
> [DURATION] [numeric](10, 0) NULL ,
> [IVR] [varchar] (50) NOT NULL ,
> [CHANNELNO] [varchar] (50) NOT NULL CONSTRAINT
> [CHANNEL_M_SCHEMECHANGE_T_FK1] FOREIGN KEY ([CHANNELNO])
> REFERENCES [dbo].[GR_CHANNEL_M] ([CHANNELNO]),
> [CALLTERMINATE] [varchar] (50) NULL)
> If I create the table GR_CALL_DETAILS_M i am getting the error
> There are no primary or candidate keys in the referenced table
> 'dbo.GR_CHANNEL_M' that match the referencing column list in the foreign
> key
> 'CHANNEL_M_SCHEMECHANGE_T_FK1'.
> How to solve this?
> thanks
> vanitha|||"vanitha" <vanitha@.discussions.microsoft.com> wrote in message
news:8B38AC26-7E65-4CCD-BBFA-BBB8BDF5A0AA@.microsoft.com...
> Hi,
> My Master table structure
>
> If I create the table GR_CALL_DETAILS_M i am getting the error
> There are no primary or candidate keys in the referenced table
> 'dbo.GR_CHANNEL_M' that match the referencing column list in the
foreign key
> 'CHANNEL_M_SCHEMECHANGE_T_FK1'.
> How to solve this?
> thanks
> vanitha
Vanitha,
The tables slightly realigned for readability:
CREATE TABLE [dbo].[GR_CHANNEL_M] (
[CHANNELNO] [varchar] (50) NOT NULL ,
[SERVICE] [varchar] (50) NOT NULL ,
[IVR] [varchar] (50) NOT NULL
CONSTRAINT [GR_CHANNEL_M_PK]
PRIMARY KEY CLUSTERED ([IVR], [CHANNELNO]),
[OPTIONAL1] [varchar] (50) NULL ,
[OPTIONAL2] [varchar] (50) NULL )
GO
My transaction table
CREATE TABLE [dbo].[GR_CALL_DETAILS_M] (
[CALLID] [varchar] (50) NOT NULL constraint
GR_CALL_DETAILS_M_PK primary
key clustered(CALLID),
[DATEANDTIME] [datetime] NULL ,
[DURATION] [numeric](10, 0) NULL ,
[IVR] [varchar] (50) NOT NULL ,
[CHANNELNO] [varchar] (50) NOT NULL
CONSTRAINT [CHANNEL_M_SCHEMECHANGE_T_FK1]
FOREIGN KEY ([CHANNELNO])
REFERENCES [dbo].[GR_CHANNEL_M] ([CHANNELNO]),
[CALLTERMINATE] [varchar] (50) NULL)
Table GR_CHANNEL_M has a PRIMARY KEY of ([IVR], [CHANNELNO]).
You cannot create a foreign key back to the CHANNELNO column because
it is not a key in its own right, but only a *part* of a key, and
has no identifiable or enforced uniqueness.
Create GR_CHANNEL_M as (or use ALTER):
CREATE TABLE [dbo].[GR_CHANNEL_M] (
[CHANNELNO] [varchar] (50) NOT NULL ,
[SERVICE] [varchar] (50) NOT NULL ,
[IVR] [varchar] (50) NOT NULL
CONSTRAINT [GR_CHANNEL_M_PK]
PRIMARY KEY CLUSTERED ([IVR], [CHANNELNO]),
[OPTIONAL1] [varchar] (50) NULL ,
[OPTIONAL2] [varchar] (50) NULL
,CONSTRAINT GR_CHANNEL_M_UNI_CHANNELNO
UNIQUE (CHANNELNO) )
Note the new CONSTRAINT at the end of the DDL.
The second table can be created after this change is added.
Sincerely,
Chris O.|||if i enforce te unique key, that means that channelno is unique, in my logic
channelno is not unique, only channelno with that ivr is unique.
thanks
vanitha
"Chris2" wrote:

> "vanitha" <vanitha@.discussions.microsoft.com> wrote in message
> news:8B38AC26-7E65-4CCD-BBFA-BBB8BDF5A0AA@.microsoft.com...
> foreign key
> Vanitha,
> The tables slightly realigned for readability:
> CREATE TABLE [dbo].[GR_CHANNEL_M] (
> [CHANNELNO] [varchar] (50) NOT NULL ,
> [SERVICE] [varchar] (50) NOT NULL ,
> [IVR] [varchar] (50) NOT NULL
> CONSTRAINT [GR_CHANNEL_M_PK]
> PRIMARY KEY CLUSTERED ([IVR], [CHANNELNO]),
> [OPTIONAL1] [varchar] (50) NULL ,
> [OPTIONAL2] [varchar] (50) NULL )
> GO
> My transaction table
> CREATE TABLE [dbo].[GR_CALL_DETAILS_M] (
> [CALLID] [varchar] (50) NOT NULL constraint
> GR_CALL_DETAILS_M_PK primary
> key clustered(CALLID),
> [DATEANDTIME] [datetime] NULL ,
> [DURATION] [numeric](10, 0) NULL ,
> [IVR] [varchar] (50) NOT NULL ,
> [CHANNELNO] [varchar] (50) NOT NULL
> CONSTRAINT [CHANNEL_M_SCHEMECHANGE_T_FK1]
> FOREIGN KEY ([CHANNELNO])
> REFERENCES [dbo].[GR_CHANNEL_M] ([CHANNELNO]),
> [CALLTERMINATE] [varchar] (50) NULL)
>
> Table GR_CHANNEL_M has a PRIMARY KEY of ([IVR], [CHANNELNO]).
> You cannot create a foreign key back to the CHANNELNO column because
> it is not a key in its own right, but only a *part* of a key, and
> has no identifiable or enforced uniqueness.
>
> Create GR_CHANNEL_M as (or use ALTER):
>
> CREATE TABLE [dbo].[GR_CHANNEL_M] (
> [CHANNELNO] [varchar] (50) NOT NULL ,
> [SERVICE] [varchar] (50) NOT NULL ,
> [IVR] [varchar] (50) NOT NULL
> CONSTRAINT [GR_CHANNEL_M_PK]
> PRIMARY KEY CLUSTERED ([IVR], [CHANNELNO]),
> [OPTIONAL1] [varchar] (50) NULL ,
> [OPTIONAL2] [varchar] (50) NULL
> ,CONSTRAINT GR_CHANNEL_M_UNI_CHANNELNO
> UNIQUE (CHANNELNO) )
> Note the new CONSTRAINT at the end of the DDL.
> The second table can be created after this change is added.
>
> Sincerely,
> Chris O.
>
>|||Then perhaps you can do this:
CREATE TABLE [dbo].[GR_CHANNEL_M] (
[CHANNELNO] [varchar] (50) NOT NULL ,
[SERVICE] [varchar] (50) NOT NULL ,
[IVR] [varchar] (50) NOT NULL CONSTRAINT [GR_CHANNEL_M_PK] PRIMARY KEY
CLUSTERED ([IVR],[CHANNELNO]),
[OPTIONAL1] [varchar] (50) NULL ,
[OPTIONAL2] [varchar] (50) NULL )
CREATE TABLE [dbo].[GR_CALL_DETAILS_M] (
[CALLID] [varchar] (50) NOT NULL constraint GR_CALL_DETAILS_M_PK primary
key clustered(CALLID),
[DATEANDTIME] [datetime] NULL ,
[DURATION] [numeric](10, 0) NULL ,
[IVR] [varchar] (50) NOT NULL ,
[CHANNELNO] [varchar] (50) NOT NULL,
CONSTRAINT [CHANNEL_M_SCHEMECHANGE_T_FK1] FOREIGN KEY ([IVR], [CHANNELNO])
REFERENCES [dbo].[GR_CHANNEL_M] ([IVR], [CHANNELNO]),
[CALLTERMINATE] [varchar] (50) NULL)
-- Ben Nevarez
"vanitha" <vanitha@.discussions.microsoft.com> wrote in message
news:D3BE275B-701A-458B-9761-A53440BCCFDD@.microsoft.com...
> if i enforce te unique key, that means that channelno is unique, in my
> logic
> channelno is not unique, only channelno with that ivr is unique.
> thanks
> vanitha
> "Chris2" wrote:
>|||"vanitha" <vanitha@.discussions.microsoft.com> wrote in message
news:D3BE275B-701A-458B-9761-A53440BCCFDD@.microsoft.com...
> "Chris2" wrote:
>
the
<snip>
> if i enforce te unique key, that means that channelno is unique,
in my logic
> channelno is not unique, only channelno with that ivr is unique.
> thanks
> vanitha
>
vanitha,
Then you cannot have a foreign key reference back to it.
May I ask if you intended for GR_CALL_DETAILS_M to reference both
IVR and CHANNELNO?
CREATE TABLE [dbo].[GR_CALL_DETAILS_M] (
[CALLID] [varchar] (50) NOT NULL constraint
GR_CALL_DETAILS_M_PK primary
key clustered(CALLID),
[DATEANDTIME] [datetime] NULL ,
[DURATION] [numeric](10, 0) NULL ,
[IVR] [varchar] (50) NOT NULL ,
[CHANNELNO] [varchar] (50) NOT NULL,
[CALLTERMINATE] [varchar] (50) NULL,
CONSTRAINT [CHANNEL_M_SCHEMECHANGE_T_FK1]
FOREIGN KEY ([IVR], [CHANNELNO])
REFERENCES [dbo].[GR_CHANNEL_M] ([IVR], [CHANNELNO])
)
Sincerely,
Chris O.

2012年3月11日星期日

Fixed Header in Reporting Service 2000

I want to create a report with SQL Server Reporting Service 2000 where I need to have a fixed header and one fixed column containg names of each row items. I tried to find "Fixed Header" property in table but could not locate it anywhere.Can anyone please kindly tell me where should i look for it?Or how to achieve this functionality?

Thank you in advance.

Bharat Gadhia.

FixedHeader is a new feature that got added in RS 2005. It was not available in 2000.|||

Hi Fang,

Thank you for the reply.

Can you tell me how to achieve this functionality in SQL Server Reporting Service 2000?

Bharat Gadhia.

2012年2月26日星期日

First Service Broker Attempt, Prajdic''s Example, Error: "queue has been disabled"

I am using the Centralized Asynchronous Auditing with Service Broker article example to set up my first Service Broker attempt. We want to start logging search criteria and search results for our product search page. We wanted it to be asynchronous and be stored in another dbase, this seemed like the perfect example.

I modified the example above to save into an Audit table we created and to read a custom message that I generated the XML for. I'm pretty certain that should all work. However, I didn't change much else but I can't get the message to send.

This is the error I'm getting in profiler:

This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742.

I am sending from one database to another within the same SQL server instance. Here are the profiler details

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry
Broker:Conversation Group Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query Larry
Broker:Message Classify Microsoft SQL Server Management Studio - Query Larry
Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Broker:Message Classify

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Message Classify

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

When I run SELECT * FROM sys.transmission_queue I get this in the transmission_status:

"One or more messages could not be delivered to the local service targeted by this dialog."

I'm hoping someone can point me in the right direciton, thanks.

Larry Grady wrote:

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Enable the destination queue using ALTER QUEUE [<queuename>] WITH STATUS = ON; During development queues often become disabled as a result of poison message prevention mechanism noticing rollbacks, see http://technet.microsoft.com/en-us/library/ms171592.aspx

|||

Ok, so it looks like the problem is before this. The real question is why is my queue being disabled. Because when I alter the queues to have WITH STATUS=ON or if I delete teh queues and services and recreate, when I run it the first time, my queue gets disabled. I'm not sure why, can't seem to find a good error message.

Here is profiler on that first run

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Conversation Group Microsoft SQL Server Management Studio - Query

Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Message Classify Microsoft SQL Server Management Studio - Query

Broker:Conversation Group Microsoft SQL Server Management Studio - Query
Broker:Conversation STARTED_INBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Activation Microsoft SQL Server Management Studio - Query
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Queue Disabled
Broker:Activation

I get no results when I run SELECT * FROM sys.transmission_queue

Any idea why my que is disabling or where i can get a better message letting me know what's going on. This is my first attempt that this so it could be something simple I'm missing.

I used that original example and only changed the send and receive stored procedures and dbase names. No other administration was done.

|||Your activated procedure is rolling back and causing the queue to be disabled. Check ERRORLOG for error messages from the activated procedure. Turn off activation and run the procedure manually to catch it's output and debug it.|||

Hey!

In the future if you have any problems you're welcome to post the error in the comments section of that article because i don't really check here so often. I'm practicaly online all the time on SQLTeam during the work day so i'd also be able to answer any question you might have.

but as i see it Remus has it handled pretty well around here so no worries Smile

Mladen

|||

Thanks, these posts helped a lot.


I had changed the XML structure and the audit table/insert from the article to meet my biz needs and as a result I wasn't querying the msgBody correctly. However, I had no idea why my queue was disabled when I ran my example. It seemed more like an administration or permission error to me, so that's what I was concentrating on. It wasn't until I started stepping through, running pieces of the sprocs on their own that I found it.

But there wasn't any kind of informative error letting me know what the problem was on the target side. I think perhaps I need to institute the same kind of error handling that is in the initiating sproc into the targe sproc. Then if there is a logic error I can have some kind of information about it.

It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

Anyway, I have my basic example working and it seems to work great. Great example articles, thanks.

|||

Larry Grady wrote:


It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

In production you should monitor queues using event notifications for QUEUE_DISABLED event. This event is fired when a poison message disables a queue and you can react to the event (eg. notify the site administrator)|||

also in my example the error that causes the activation proc to rollback gets saved in the AuditErrors table.

you might want to check there for troubleshooting.

|||

My project is moving along nicely. I have my queues working properly and i'm writing data to my audit tables.

I have one more issue, although it's not directly SSB related, it is part of this project.

My main stored procedure is a product search. For each product search we have to save the Criteria that was used and then we have to save the products that were returned. The stored procedure itself is a really long and complicated proc that builds a dynamic sql string. Then at the end it executes it.


The way i ahve it working now

..... Process to build @.SQLString.....

EXEC(@.SQLString)

This returns my search results. Now i've added after it my initiator query. This query creates the AuditMsg in XML and loads it into a message which is que'd and sent to my target database where this data is inserted into an audit table.

EXEC usp_SendSearchAudit @.userID,@.brandID,....other criteria....., @.source

This is where i'm a little stuck. I need to then take the output, the actual records that are returned, and store 3 of the returned fields into an audit table. The results can be anywhere from a few records to a couple thousand.

I was thinking of INSERTING into a temp table and then sending that and doing a SELECT FOR XML to send to the audit table and then doing a SELECT @.tempResults to return from the main stored procedure. I don't know if that's really teh best way to do this. Anyone have any suggestions. I'm kind of struggling with the right way to do this. A few lines of pseudo code may go a long way. Thanks.

|||

i'm not quite sure i understand what you're trying to do...

could you post some sample code or pseudo code?

|||

Here is my initial search query (actually much of the dyamic part is stripped out because it doens't apply to the problem).

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

ALTER PROCEDURE [dbo].[spResults_Select]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.priceFrom real,

@.priceTo real,

[MORE CRITERIA]

@.bHiResImg int

)

AS

BEGIN

[LOTS OF CODE HERE BUILDING SQL STRING. Actually a TEMP table is build and then we select off of that temp table, it's very complicated. We plan on optimizing later but for now it is what it is]

[the string is @.SelectSQL]

EXEC(@.SelectSQL)

[This is where the original stored procedure ended. This EXEC line returns the search results back to the Search form]

[New Code: This stored procedure is an initiator query that takes the parameters, formulates it into XML, creates a messages and send it to SSB. This is for the search criteriea, this is working]

EXEC usp_SendSearchAudit

@.userID=@.userID,

@.brandList=@.brandList,

@.subCatList=@.subCatList,

@.keywordSearch=@.keywordSearch,

@.priceFrom=@.priceFrom,

@.priceTo=@.priceTo,

@.bHiResImg=@.bHiResImg,

@.source=@.source

[This is where I am stuck. EXEC(@.SelectSQL) returns a bunch of records to the searchresults object. However, I need to take those same records and extract the Product_ID from each and save it to the audit tables in teh other database. I am going to create XML object out of it, create a message, send it to SSB).

Something like

EXEC ups_SendSearchResultsAudit

[parameters]

Or, maybe It would all be a part of the usp_SendSearchAudit above, that I would pass a TABLE parameter into that stored procedure?

END

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

ALTER PROCEDURE [dbo].[usp_SendSearchAudit]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.keywordSearch varchar(2000),

@.priceFrom real,

@.priceTo real,

@.bHiResImg int,

@.source varchar(10)

)

AS

BEGIN

DECLARE @.AuditMsg XML

SELECT @.AuditMsg = '<AuditMsg MsgType="Search">

<Search>

<userID>' + @.userID + '</userID>

<brands>' + (SELECT 1 as Tag, NULL as Parent, gID [brandID!1] FROM dbo.f_ConvertGuidList_to_Table(@.brandList) Brands FOR XML EXPLICIT) + '</brands>

<subCats>' + (SELECT 1 as Tag, NULL as Parent, string [subCatID!1] FROM dbo.f_ConvertStringList_to_Table(@.subCatList) SubCats FOR XML EXPLICIT) + '</subCats>

<keywords>' + @.keywordSearch + '</keywords>

<priceFrom>' + CONVERT(varchar(10),@.priceFrom) + '</priceFrom>

<priceTo>' + CONVERT(varchar(10),@.priceTo) + '</priceTo>

<hiRes>' + CONVERT(varchar(10),@.bHiResImg) + '</hiRes>

<source>' + @.source + '</source>

</Search>

</AuditMsg>'

EXEC dbo.usp_SendAuditData @.AuditMsg

--SELECT @.AuditMsg

END

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

ALTER PROCEDURE [dbo].[usp_SendAuditData]

(

@.AuditedData XML

)

AS

BEGIN

BEGIN TRY

DECLARE @.dlgId UNIQUEIDENTIFIER

-- Begin the dialog, either with existing or new Id

BEGIN DIALOG @.dlgId

FROM SERVICE [//Audit/DataSender]

TO SERVICE '//Audit/DataWriter',

'X1X1X1X1-X1X1-X1X1-X1X1-X1X1X1X1X1X1'

ON CONTRACT [//Audit/Contract]

WITH ENCRYPTION = OFF;

;SEND ON CONVERSATION @.dlgId

MESSAGE TYPE [//Audit/Message] (@.AuditedData)

END TRY

END

I have stripped out a ton of code that doesn't really pertain, but this is basically what i'm doing.

|||

you know... that is the coolest GUID i've seen in a while!

well if a temp table is created then you could select from that temp table.

for temp tabel scopes read this post of mine:

http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx

you can also use a global temp table with a guid for name to avoid problems.

First Service Broker Attempt, Prajdic''s Example, Error: "queue has been disabled"

I am using the Centralized Asynchronous Auditing with Service Broker article example to set up my first Service Broker attempt. We want to start logging search criteria and search results for our product search page. We wanted it to be asynchronous and be stored in another dbase, this seemed like the perfect example.

I modified the example above to save into an Audit table we created and to read a custom message that I generated the XML for. I'm pretty certain that should all work. However, I didn't change much else but I can't get the message to send.

This is the error I'm getting in profiler:

This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742.

I am sending from one database to another within the same SQL server instance. Here are the profiler details

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry
Broker:Conversation Group Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query Larry
Broker:Message Classify Microsoft SQL Server Management Studio - Query Larry
Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Broker:Message Classify

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Message Classify

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

When I run SELECT * FROM sys.transmission_queue I get this in the transmission_status:

"One or more messages could not be delivered to the local service targeted by this dialog."

I'm hoping someone can point me in the right direciton, thanks.

Larry Grady wrote:

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Enable the destination queue using ALTER QUEUE [<queuename>] WITH STATUS = ON; During development queues often become disabled as a result of poison message prevention mechanism noticing rollbacks, see http://technet.microsoft.com/en-us/library/ms171592.aspx

|||

Ok, so it looks like the problem is before this. The real question is why is my queue being disabled. Because when I alter the queues to have WITH STATUS=ON or if I delete teh queues and services and recreate, when I run it the first time, my queue gets disabled. I'm not sure why, can't seem to find a good error message.

Here is profiler on that first run

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Conversation Group Microsoft SQL Server Management Studio - Query

Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Message Classify Microsoft SQL Server Management Studio - Query

Broker:Conversation Group Microsoft SQL Server Management Studio - Query
Broker:Conversation STARTED_INBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Activation Microsoft SQL Server Management Studio - Query
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Queue Disabled
Broker:Activation

I get no results when I run SELECT * FROM sys.transmission_queue

Any idea why my que is disabling or where i can get a better message letting me know what's going on. This is my first attempt that this so it could be something simple I'm missing.

I used that original example and only changed the send and receive stored procedures and dbase names. No other administration was done.

|||Your activated procedure is rolling back and causing the queue to be disabled. Check ERRORLOG for error messages from the activated procedure. Turn off activation and run the procedure manually to catch it's output and debug it.|||

Hey!

In the future if you have any problems you're welcome to post the error in the comments section of that article because i don't really check here so often. I'm practicaly online all the time on SQLTeam during the work day so i'd also be able to answer any question you might have.

but as i see it Remus has it handled pretty well around here so no worries Smile

Mladen

|||

Thanks, these posts helped a lot.


I had changed the XML structure and the audit table/insert from the article to meet my biz needs and as a result I wasn't querying the msgBody correctly. However, I had no idea why my queue was disabled when I ran my example. It seemed more like an administration or permission error to me, so that's what I was concentrating on. It wasn't until I started stepping through, running pieces of the sprocs on their own that I found it.

But there wasn't any kind of informative error letting me know what the problem was on the target side. I think perhaps I need to institute the same kind of error handling that is in the initiating sproc into the targe sproc. Then if there is a logic error I can have some kind of information about it.

It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

Anyway, I have my basic example working and it seems to work great. Great example articles, thanks.

|||

Larry Grady wrote:


It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

In production you should monitor queues using event notifications for QUEUE_DISABLED event. This event is fired when a poison message disables a queue and you can react to the event (eg. notify the site administrator)|||

also in my example the error that causes the activation proc to rollback gets saved in the AuditErrors table.

you might want to check there for troubleshooting.

|||

My project is moving along nicely. I have my queues working properly and i'm writing data to my audit tables.

I have one more issue, although it's not directly SSB related, it is part of this project.

My main stored procedure is a product search. For each product search we have to save the Criteria that was used and then we have to save the products that were returned. The stored procedure itself is a really long and complicated proc that builds a dynamic sql string. Then at the end it executes it.


The way i ahve it working now

..... Process to build @.SQLString.....

EXEC(@.SQLString)

This returns my search results. Now i've added after it my initiator query. This query creates the AuditMsg in XML and loads it into a message which is que'd and sent to my target database where this data is inserted into an audit table.

EXEC usp_SendSearchAudit @.userID,@.brandID,....other criteria....., @.source

This is where i'm a little stuck. I need to then take the output, the actual records that are returned, and store 3 of the returned fields into an audit table. The results can be anywhere from a few records to a couple thousand.

I was thinking of INSERTING into a temp table and then sending that and doing a SELECT FOR XML to send to the audit table and then doing a SELECT @.tempResults to return from the main stored procedure. I don't know if that's really teh best way to do this. Anyone have any suggestions. I'm kind of struggling with the right way to do this. A few lines of pseudo code may go a long way. Thanks.

|||

i'm not quite sure i understand what you're trying to do...

could you post some sample code or pseudo code?

|||

Here is my initial search query (actually much of the dyamic part is stripped out because it doens't apply to the problem).

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

ALTER PROCEDURE [dbo].[spResults_Select]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.priceFrom real,

@.priceTo real,

[MORE CRITERIA]

@.bHiResImg int

)

AS

BEGIN

[LOTS OF CODE HERE BUILDING SQL STRING. Actually a TEMP table is build and then we select off of that temp table, it's very complicated. We plan on optimizing later but for now it is what it is]

[the string is @.SelectSQL]

EXEC(@.SelectSQL)

[This is where the original stored procedure ended. This EXEC line returns the search results back to the Search form]

[New Code: This stored procedure is an initiator query that takes the parameters, formulates it into XML, creates a messages and send it to SSB. This is for the search criteriea, this is working]

EXEC usp_SendSearchAudit

@.userID=@.userID,

@.brandList=@.brandList,

@.subCatList=@.subCatList,

@.keywordSearch=@.keywordSearch,

@.priceFrom=@.priceFrom,

@.priceTo=@.priceTo,

@.bHiResImg=@.bHiResImg,

@.source=@.source

[This is where I am stuck. EXEC(@.SelectSQL) returns a bunch of records to the searchresults object. However, I need to take those same records and extract the Product_ID from each and save it to the audit tables in teh other database. I am going to create XML object out of it, create a message, send it to SSB).

Something like

EXEC ups_SendSearchResultsAudit

[parameters]

Or, maybe It would all be a part of the usp_SendSearchAudit above, that I would pass a TABLE parameter into that stored procedure?

END

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

ALTER PROCEDURE [dbo].[usp_SendSearchAudit]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.keywordSearch varchar(2000),

@.priceFrom real,

@.priceTo real,

@.bHiResImg int,

@.source varchar(10)

)

AS

BEGIN

DECLARE @.AuditMsg XML

SELECT @.AuditMsg = '<AuditMsg MsgType="Search">

<Search>

<userID>' + @.userID + '</userID>

<brands>' + (SELECT 1 as Tag, NULL as Parent, gID [brandID!1] FROM dbo.f_ConvertGuidList_to_Table(@.brandList) Brands FOR XML EXPLICIT) + '</brands>

<subCats>' + (SELECT 1 as Tag, NULL as Parent, string [subCatID!1] FROM dbo.f_ConvertStringList_to_Table(@.subCatList) SubCats FOR XML EXPLICIT) + '</subCats>

<keywords>' + @.keywordSearch + '</keywords>

<priceFrom>' + CONVERT(varchar(10),@.priceFrom) + '</priceFrom>

<priceTo>' + CONVERT(varchar(10),@.priceTo) + '</priceTo>

<hiRes>' + CONVERT(varchar(10),@.bHiResImg) + '</hiRes>

<source>' + @.source + '</source>

</Search>

</AuditMsg>'

EXEC dbo.usp_SendAuditData @.AuditMsg

--SELECT @.AuditMsg

END

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

ALTER PROCEDURE [dbo].[usp_SendAuditData]

(

@.AuditedData XML

)

AS

BEGIN

BEGIN TRY

DECLARE @.dlgId UNIQUEIDENTIFIER

-- Begin the dialog, either with existing or new Id

BEGIN DIALOG @.dlgId

FROM SERVICE [//Audit/DataSender]

TO SERVICE '//Audit/DataWriter',

'X1X1X1X1-X1X1-X1X1-X1X1-X1X1X1X1X1X1'

ON CONTRACT [//Audit/Contract]

WITH ENCRYPTION = OFF;

;SEND ON CONVERSATION @.dlgId

MESSAGE TYPE [//Audit/Message] (@.AuditedData)

END TRY

END

I have stripped out a ton of code that doesn't really pertain, but this is basically what i'm doing.

|||

you know... that is the coolest GUID i've seen in a while!

well if a temp table is created then you could select from that temp table.

for temp tabel scopes read this post of mine:

http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx

you can also use a global temp table with a guid for name to avoid problems.

First Service Broker Attempt, Prajdic''s Example, Error: "queue has been disabled"

I am using the Centralized Asynchronous Auditing with Service Broker article example to set up my first Service Broker attempt. We want to start logging search criteria and search results for our product search page. We wanted it to be asynchronous and be stored in another dbase, this seemed like the perfect example.

I modified the example above to save into an Audit table we created and to read a custom message that I generated the XML for. I'm pretty certain that should all work. However, I didn't change much else but I can't get the message to send.

This is the error I'm getting in profiler:

This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742.

I am sending from one database to another within the same SQL server instance. Here are the profiler details

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry
Broker:Conversation Group Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query Larry
Broker:Message Classify Microsoft SQL Server Management Studio - Query Larry
Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Broker:Message Classify

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Message Classify

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

When I run SELECT * FROM sys.transmission_queue I get this in the transmission_status:

"One or more messages could not be delivered to the local service targeted by this dialog."

I'm hoping someone can point me in the right direciton, thanks.

Larry Grady wrote:

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Enable the destination queue using ALTER QUEUE [<queuename>] WITH STATUS = ON; During development queues often become disabled as a result of poison message prevention mechanism noticing rollbacks, see http://technet.microsoft.com/en-us/library/ms171592.aspx

|||

Ok, so it looks like the problem is before this. The real question is why is my queue being disabled. Because when I alter the queues to have WITH STATUS=ON or if I delete teh queues and services and recreate, when I run it the first time, my queue gets disabled. I'm not sure why, can't seem to find a good error message.

Here is profiler on that first run

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Conversation Group Microsoft SQL Server Management Studio - Query

Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Message Classify Microsoft SQL Server Management Studio - Query

Broker:Conversation Group Microsoft SQL Server Management Studio - Query
Broker:Conversation STARTED_INBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Activation Microsoft SQL Server Management Studio - Query
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Queue Disabled
Broker:Activation

I get no results when I run SELECT * FROM sys.transmission_queue

Any idea why my que is disabling or where i can get a better message letting me know what's going on. This is my first attempt that this so it could be something simple I'm missing.

I used that original example and only changed the send and receive stored procedures and dbase names. No other administration was done.

|||Your activated procedure is rolling back and causing the queue to be disabled. Check ERRORLOG for error messages from the activated procedure. Turn off activation and run the procedure manually to catch it's output and debug it.|||

Hey!

In the future if you have any problems you're welcome to post the error in the comments section of that article because i don't really check here so often. I'm practicaly online all the time on SQLTeam during the work day so i'd also be able to answer any question you might have.

but as i see it Remus has it handled pretty well around here so no worries Smile

Mladen

|||

Thanks, these posts helped a lot.


I had changed the XML structure and the audit table/insert from the article to meet my biz needs and as a result I wasn't querying the msgBody correctly. However, I had no idea why my queue was disabled when I ran my example. It seemed more like an administration or permission error to me, so that's what I was concentrating on. It wasn't until I started stepping through, running pieces of the sprocs on their own that I found it.

But there wasn't any kind of informative error letting me know what the problem was on the target side. I think perhaps I need to institute the same kind of error handling that is in the initiating sproc into the targe sproc. Then if there is a logic error I can have some kind of information about it.

It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

Anyway, I have my basic example working and it seems to work great. Great example articles, thanks.

|||

Larry Grady wrote:


It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

In production you should monitor queues using event notifications for QUEUE_DISABLED event. This event is fired when a poison message disables a queue and you can react to the event (eg. notify the site administrator)|||

also in my example the error that causes the activation proc to rollback gets saved in the AuditErrors table.

you might want to check there for troubleshooting.

|||

My project is moving along nicely. I have my queues working properly and i'm writing data to my audit tables.

I have one more issue, although it's not directly SSB related, it is part of this project.

My main stored procedure is a product search. For each product search we have to save the Criteria that was used and then we have to save the products that were returned. The stored procedure itself is a really long and complicated proc that builds a dynamic sql string. Then at the end it executes it.


The way i ahve it working now

..... Process to build @.SQLString.....

EXEC(@.SQLString)

This returns my search results. Now i've added after it my initiator query. This query creates the AuditMsg in XML and loads it into a message which is que'd and sent to my target database where this data is inserted into an audit table.

EXEC usp_SendSearchAudit @.userID,@.brandID,....other criteria....., @.source

This is where i'm a little stuck. I need to then take the output, the actual records that are returned, and store 3 of the returned fields into an audit table. The results can be anywhere from a few records to a couple thousand.

I was thinking of INSERTING into a temp table and then sending that and doing a SELECT FOR XML to send to the audit table and then doing a SELECT @.tempResults to return from the main stored procedure. I don't know if that's really teh best way to do this. Anyone have any suggestions. I'm kind of struggling with the right way to do this. A few lines of pseudo code may go a long way. Thanks.

|||

i'm not quite sure i understand what you're trying to do...

could you post some sample code or pseudo code?

|||

Here is my initial search query (actually much of the dyamic part is stripped out because it doens't apply to the problem).

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

ALTER PROCEDURE [dbo].[spResults_Select]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.priceFrom real,

@.priceTo real,

[MORE CRITERIA]

@.bHiResImg int

)

AS

BEGIN

[LOTS OF CODE HERE BUILDING SQL STRING. Actually a TEMP table is build and then we select off of that temp table, it's very complicated. We plan on optimizing later but for now it is what it is]

[the string is @.SelectSQL]

EXEC(@.SelectSQL)

[This is where the original stored procedure ended. This EXEC line returns the search results back to the Search form]

[New Code: This stored procedure is an initiator query that takes the parameters, formulates it into XML, creates a messages and send it to SSB. This is for the search criteriea, this is working]

EXEC usp_SendSearchAudit

@.userID=@.userID,

@.brandList=@.brandList,

@.subCatList=@.subCatList,

@.keywordSearch=@.keywordSearch,

@.priceFrom=@.priceFrom,

@.priceTo=@.priceTo,

@.bHiResImg=@.bHiResImg,

@.source=@.source

[This is where I am stuck. EXEC(@.SelectSQL) returns a bunch of records to the searchresults object. However, I need to take those same records and extract the Product_ID from each and save it to the audit tables in teh other database. I am going to create XML object out of it, create a message, send it to SSB).

Something like

EXEC ups_SendSearchResultsAudit

[parameters]

Or, maybe It would all be a part of the usp_SendSearchAudit above, that I would pass a TABLE parameter into that stored procedure?

END

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

ALTER PROCEDURE [dbo].[usp_SendSearchAudit]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.keywordSearch varchar(2000),

@.priceFrom real,

@.priceTo real,

@.bHiResImg int,

@.source varchar(10)

)

AS

BEGIN

DECLARE @.AuditMsg XML

SELECT @.AuditMsg = '<AuditMsg MsgType="Search">

<Search>

<userID>' + @.userID + '</userID>

<brands>' + (SELECT 1 as Tag, NULL as Parent, gID [brandID!1] FROM dbo.f_ConvertGuidList_to_Table(@.brandList) Brands FOR XML EXPLICIT) + '</brands>

<subCats>' + (SELECT 1 as Tag, NULL as Parent, string [subCatID!1] FROM dbo.f_ConvertStringList_to_Table(@.subCatList) SubCats FOR XML EXPLICIT) + '</subCats>

<keywords>' + @.keywordSearch + '</keywords>

<priceFrom>' + CONVERT(varchar(10),@.priceFrom) + '</priceFrom>

<priceTo>' + CONVERT(varchar(10),@.priceTo) + '</priceTo>

<hiRes>' + CONVERT(varchar(10),@.bHiResImg) + '</hiRes>

<source>' + @.source + '</source>

</Search>

</AuditMsg>'

EXEC dbo.usp_SendAuditData @.AuditMsg

--SELECT @.AuditMsg

END

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

ALTER PROCEDURE [dbo].[usp_SendAuditData]

(

@.AuditedData XML

)

AS

BEGIN

BEGIN TRY

DECLARE @.dlgId UNIQUEIDENTIFIER

-- Begin the dialog, either with existing or new Id

BEGIN DIALOG @.dlgId

FROM SERVICE [//Audit/DataSender]

TO SERVICE '//Audit/DataWriter',

'X1X1X1X1-X1X1-X1X1-X1X1-X1X1X1X1X1X1'

ON CONTRACT [//Audit/Contract]

WITH ENCRYPTION = OFF;

;SEND ON CONVERSATION @.dlgId

MESSAGE TYPE [//Audit/Message] (@.AuditedData)

END TRY

END

I have stripped out a ton of code that doesn't really pertain, but this is basically what i'm doing.

|||

you know... that is the coolest GUID i've seen in a while!

well if a temp table is created then you could select from that temp table.

for temp tabel scopes read this post of mine:

http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx

you can also use a global temp table with a guid for name to avoid problems.

First Service Broker Attempt, Prajdic''s Example, Error: "queue has been disabled"

I am using the Centralized Asynchronous Auditing with Service Broker article example to set up my first Service Broker attempt. We want to start logging search criteria and search results for our product search page. We wanted it to be asynchronous and be stored in another dbase, this seemed like the perfect example.

I modified the example above to save into an Audit table we created and to read a custom message that I generated the XML for. I'm pretty certain that should all work. However, I didn't change much else but I can't get the message to send.

This is the error I'm getting in profiler:

This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742.

I am sending from one database to another within the same SQL server instance. Here are the profiler details

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry
Broker:Conversation Group Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query Larry
Broker:Message Classify Microsoft SQL Server Management Studio - Query Larry
Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Broker:Message Classify

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Message Classify

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

When I run SELECT * FROM sys.transmission_queue I get this in the transmission_status:

"One or more messages could not be delivered to the local service targeted by this dialog."

I'm hoping someone can point me in the right direciton, thanks.

Larry Grady wrote:

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Enable the destination queue using ALTER QUEUE [<queuename>] WITH STATUS = ON; During development queues often become disabled as a result of poison message prevention mechanism noticing rollbacks, see http://technet.microsoft.com/en-us/library/ms171592.aspx

|||

Ok, so it looks like the problem is before this. The real question is why is my queue being disabled. Because when I alter the queues to have WITH STATUS=ON or if I delete teh queues and services and recreate, when I run it the first time, my queue gets disabled. I'm not sure why, can't seem to find a good error message.

Here is profiler on that first run

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Conversation Group Microsoft SQL Server Management Studio - Query

Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Message Classify Microsoft SQL Server Management Studio - Query

Broker:Conversation Group Microsoft SQL Server Management Studio - Query
Broker:Conversation STARTED_INBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Activation Microsoft SQL Server Management Studio - Query
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Queue Disabled
Broker:Activation

I get no results when I run SELECT * FROM sys.transmission_queue

Any idea why my que is disabling or where i can get a better message letting me know what's going on. This is my first attempt that this so it could be something simple I'm missing.

I used that original example and only changed the send and receive stored procedures and dbase names. No other administration was done.

|||Your activated procedure is rolling back and causing the queue to be disabled. Check ERRORLOG for error messages from the activated procedure. Turn off activation and run the procedure manually to catch it's output and debug it.|||

Hey!

In the future if you have any problems you're welcome to post the error in the comments section of that article because i don't really check here so often. I'm practicaly online all the time on SQLTeam during the work day so i'd also be able to answer any question you might have.

but as i see it Remus has it handled pretty well around here so no worries Smile

Mladen

|||

Thanks, these posts helped a lot.


I had changed the XML structure and the audit table/insert from the article to meet my biz needs and as a result I wasn't querying the msgBody correctly. However, I had no idea why my queue was disabled when I ran my example. It seemed more like an administration or permission error to me, so that's what I was concentrating on. It wasn't until I started stepping through, running pieces of the sprocs on their own that I found it.

But there wasn't any kind of informative error letting me know what the problem was on the target side. I think perhaps I need to institute the same kind of error handling that is in the initiating sproc into the targe sproc. Then if there is a logic error I can have some kind of information about it.

It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

Anyway, I have my basic example working and it seems to work great. Great example articles, thanks.

|||

Larry Grady wrote:


It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

In production you should monitor queues using event notifications for QUEUE_DISABLED event. This event is fired when a poison message disables a queue and you can react to the event (eg. notify the site administrator)|||

also in my example the error that causes the activation proc to rollback gets saved in the AuditErrors table.

you might want to check there for troubleshooting.

|||

My project is moving along nicely. I have my queues working properly and i'm writing data to my audit tables.

I have one more issue, although it's not directly SSB related, it is part of this project.

My main stored procedure is a product search. For each product search we have to save the Criteria that was used and then we have to save the products that were returned. The stored procedure itself is a really long and complicated proc that builds a dynamic sql string. Then at the end it executes it.


The way i ahve it working now

..... Process to build @.SQLString.....

EXEC(@.SQLString)

This returns my search results. Now i've added after it my initiator query. This query creates the AuditMsg in XML and loads it into a message which is que'd and sent to my target database where this data is inserted into an audit table.

EXEC usp_SendSearchAudit @.userID,@.brandID,....other criteria....., @.source

This is where i'm a little stuck. I need to then take the output, the actual records that are returned, and store 3 of the returned fields into an audit table. The results can be anywhere from a few records to a couple thousand.

I was thinking of INSERTING into a temp table and then sending that and doing a SELECT FOR XML to send to the audit table and then doing a SELECT @.tempResults to return from the main stored procedure. I don't know if that's really teh best way to do this. Anyone have any suggestions. I'm kind of struggling with the right way to do this. A few lines of pseudo code may go a long way. Thanks.

|||

i'm not quite sure i understand what you're trying to do...

could you post some sample code or pseudo code?

|||

Here is my initial search query (actually much of the dyamic part is stripped out because it doens't apply to the problem).

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

ALTER PROCEDURE [dbo].[spResults_Select]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.priceFrom real,

@.priceTo real,

[MORE CRITERIA]

@.bHiResImg int

)

AS

BEGIN

[LOTS OF CODE HERE BUILDING SQL STRING. Actually a TEMP table is build and then we select off of that temp table, it's very complicated. We plan on optimizing later but for now it is what it is]

[the string is @.SelectSQL]

EXEC(@.SelectSQL)

[This is where the original stored procedure ended. This EXEC line returns the search results back to the Search form]

[New Code: This stored procedure is an initiator query that takes the parameters, formulates it into XML, creates a messages and send it to SSB. This is for the search criteriea, this is working]

EXEC usp_SendSearchAudit

@.userID=@.userID,

@.brandList=@.brandList,

@.subCatList=@.subCatList,

@.keywordSearch=@.keywordSearch,

@.priceFrom=@.priceFrom,

@.priceTo=@.priceTo,

@.bHiResImg=@.bHiResImg,

@.source=@.source

[This is where I am stuck. EXEC(@.SelectSQL) returns a bunch of records to the searchresults object. However, I need to take those same records and extract the Product_ID from each and save it to the audit tables in teh other database. I am going to create XML object out of it, create a message, send it to SSB).

Something like

EXEC ups_SendSearchResultsAudit

[parameters]

Or, maybe It would all be a part of the usp_SendSearchAudit above, that I would pass a TABLE parameter into that stored procedure?

END

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

ALTER PROCEDURE [dbo].[usp_SendSearchAudit]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.keywordSearch varchar(2000),

@.priceFrom real,

@.priceTo real,

@.bHiResImg int,

@.source varchar(10)

)

AS

BEGIN

DECLARE @.AuditMsg XML

SELECT @.AuditMsg = '<AuditMsg MsgType="Search">

<Search>

<userID>' + @.userID + '</userID>

<brands>' + (SELECT 1 as Tag, NULL as Parent, gID [brandID!1] FROM dbo.f_ConvertGuidList_to_Table(@.brandList) Brands FOR XML EXPLICIT) + '</brands>

<subCats>' + (SELECT 1 as Tag, NULL as Parent, string [subCatID!1] FROM dbo.f_ConvertStringList_to_Table(@.subCatList) SubCats FOR XML EXPLICIT) + '</subCats>

<keywords>' + @.keywordSearch + '</keywords>

<priceFrom>' + CONVERT(varchar(10),@.priceFrom) + '</priceFrom>

<priceTo>' + CONVERT(varchar(10),@.priceTo) + '</priceTo>

<hiRes>' + CONVERT(varchar(10),@.bHiResImg) + '</hiRes>

<source>' + @.source + '</source>

</Search>

</AuditMsg>'

EXEC dbo.usp_SendAuditData @.AuditMsg

--SELECT @.AuditMsg

END

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

ALTER PROCEDURE [dbo].[usp_SendAuditData]

(

@.AuditedData XML

)

AS

BEGIN

BEGIN TRY

DECLARE @.dlgId UNIQUEIDENTIFIER

-- Begin the dialog, either with existing or new Id

BEGIN DIALOG @.dlgId

FROM SERVICE [//Audit/DataSender]

TO SERVICE '//Audit/DataWriter',

'X1X1X1X1-X1X1-X1X1-X1X1-X1X1X1X1X1X1'

ON CONTRACT [//Audit/Contract]

WITH ENCRYPTION = OFF;

;SEND ON CONVERSATION @.dlgId

MESSAGE TYPE [//Audit/Message] (@.AuditedData)

END TRY

END

I have stripped out a ton of code that doesn't really pertain, but this is basically what i'm doing.

|||

you know... that is the coolest GUID i've seen in a while!

well if a temp table is created then you could select from that temp table.

for temp tabel scopes read this post of mine:

http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx

you can also use a global temp table with a guid for name to avoid problems.

First Service Broker Attempt, Prajdic''s Example, Error: "queue has been disabled"

I am using the Centralized Asynchronous Auditing with Service Broker article example to set up my first Service Broker attempt. We want to start logging search criteria and search results for our product search page. We wanted it to be asynchronous and be stored in another dbase, this seemed like the perfect example.

I modified the example above to save into an Audit table we created and to read a custom message that I generated the XML for. I'm pretty certain that should all work. However, I didn't change much else but I can't get the message to send.

This is the error I'm getting in profiler:

This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742.

I am sending from one database to another within the same SQL server instance. Here are the profiler details

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry
Broker:Conversation Group Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query Larry
Broker:Message Classify Microsoft SQL Server Management Studio - Query Larry
Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Broker:Message Classify

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Message Classify

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

When I run SELECT * FROM sys.transmission_queue I get this in the transmission_status:

"One or more messages could not be delivered to the local service targeted by this dialog."

I'm hoping someone can point me in the right direciton, thanks.

Larry Grady wrote:

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Enable the destination queue using ALTER QUEUE [<queuename>] WITH STATUS = ON; During development queues often become disabled as a result of poison message prevention mechanism noticing rollbacks, see http://technet.microsoft.com/en-us/library/ms171592.aspx

|||

Ok, so it looks like the problem is before this. The real question is why is my queue being disabled. Because when I alter the queues to have WITH STATUS=ON or if I delete teh queues and services and recreate, when I run it the first time, my queue gets disabled. I'm not sure why, can't seem to find a good error message.

Here is profiler on that first run

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Conversation Group Microsoft SQL Server Management Studio - Query

Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Message Classify Microsoft SQL Server Management Studio - Query

Broker:Conversation Group Microsoft SQL Server Management Studio - Query
Broker:Conversation STARTED_INBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Activation Microsoft SQL Server Management Studio - Query
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Queue Disabled
Broker:Activation

I get no results when I run SELECT * FROM sys.transmission_queue

Any idea why my que is disabling or where i can get a better message letting me know what's going on. This is my first attempt that this so it could be something simple I'm missing.

I used that original example and only changed the send and receive stored procedures and dbase names. No other administration was done.

|||Your activated procedure is rolling back and causing the queue to be disabled. Check ERRORLOG for error messages from the activated procedure. Turn off activation and run the procedure manually to catch it's output and debug it.|||

Hey!

In the future if you have any problems you're welcome to post the error in the comments section of that article because i don't really check here so often. I'm practicaly online all the time on SQLTeam during the work day so i'd also be able to answer any question you might have.

but as i see it Remus has it handled pretty well around here so no worries Smile

Mladen

|||

Thanks, these posts helped a lot.


I had changed the XML structure and the audit table/insert from the article to meet my biz needs and as a result I wasn't querying the msgBody correctly. However, I had no idea why my queue was disabled when I ran my example. It seemed more like an administration or permission error to me, so that's what I was concentrating on. It wasn't until I started stepping through, running pieces of the sprocs on their own that I found it.

But there wasn't any kind of informative error letting me know what the problem was on the target side. I think perhaps I need to institute the same kind of error handling that is in the initiating sproc into the targe sproc. Then if there is a logic error I can have some kind of information about it.

It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

Anyway, I have my basic example working and it seems to work great. Great example articles, thanks.

|||

Larry Grady wrote:


It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

In production you should monitor queues using event notifications for QUEUE_DISABLED event. This event is fired when a poison message disables a queue and you can react to the event (eg. notify the site administrator)|||

also in my example the error that causes the activation proc to rollback gets saved in the AuditErrors table.

you might want to check there for troubleshooting.

|||

My project is moving along nicely. I have my queues working properly and i'm writing data to my audit tables.

I have one more issue, although it's not directly SSB related, it is part of this project.

My main stored procedure is a product search. For each product search we have to save the Criteria that was used and then we have to save the products that were returned. The stored procedure itself is a really long and complicated proc that builds a dynamic sql string. Then at the end it executes it.


The way i ahve it working now

..... Process to build @.SQLString.....

EXEC(@.SQLString)

This returns my search results. Now i've added after it my initiator query. This query creates the AuditMsg in XML and loads it into a message which is que'd and sent to my target database where this data is inserted into an audit table.

EXEC usp_SendSearchAudit @.userID,@.brandID,....other criteria....., @.source

This is where i'm a little stuck. I need to then take the output, the actual records that are returned, and store 3 of the returned fields into an audit table. The results can be anywhere from a few records to a couple thousand.

I was thinking of INSERTING into a temp table and then sending that and doing a SELECT FOR XML to send to the audit table and then doing a SELECT @.tempResults to return from the main stored procedure. I don't know if that's really teh best way to do this. Anyone have any suggestions. I'm kind of struggling with the right way to do this. A few lines of pseudo code may go a long way. Thanks.

|||

i'm not quite sure i understand what you're trying to do...

could you post some sample code or pseudo code?

|||

Here is my initial search query (actually much of the dyamic part is stripped out because it doens't apply to the problem).

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

ALTER PROCEDURE [dbo].[spResults_Select]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.priceFrom real,

@.priceTo real,

[MORE CRITERIA]

@.bHiResImg int

)

AS

BEGIN

[LOTS OF CODE HERE BUILDING SQL STRING. Actually a TEMP table is build and then we select off of that temp table, it's very complicated. We plan on optimizing later but for now it is what it is]

[the string is @.SelectSQL]

EXEC(@.SelectSQL)

[This is where the original stored procedure ended. This EXEC line returns the search results back to the Search form]

[New Code: This stored procedure is an initiator query that takes the parameters, formulates it into XML, creates a messages and send it to SSB. This is for the search criteriea, this is working]

EXEC usp_SendSearchAudit

@.userID=@.userID,

@.brandList=@.brandList,

@.subCatList=@.subCatList,

@.keywordSearch=@.keywordSearch,

@.priceFrom=@.priceFrom,

@.priceTo=@.priceTo,

@.bHiResImg=@.bHiResImg,

@.source=@.source

[This is where I am stuck. EXEC(@.SelectSQL) returns a bunch of records to the searchresults object. However, I need to take those same records and extract the Product_ID from each and save it to the audit tables in teh other database. I am going to create XML object out of it, create a message, send it to SSB).

Something like

EXEC ups_SendSearchResultsAudit

[parameters]

Or, maybe It would all be a part of the usp_SendSearchAudit above, that I would pass a TABLE parameter into that stored procedure?

END

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

ALTER PROCEDURE [dbo].[usp_SendSearchAudit]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.keywordSearch varchar(2000),

@.priceFrom real,

@.priceTo real,

@.bHiResImg int,

@.source varchar(10)

)

AS

BEGIN

DECLARE @.AuditMsg XML

SELECT @.AuditMsg = '<AuditMsg MsgType="Search">

<Search>

<userID>' + @.userID + '</userID>

<brands>' + (SELECT 1 as Tag, NULL as Parent, gID [brandID!1] FROM dbo.f_ConvertGuidList_to_Table(@.brandList) Brands FOR XML EXPLICIT) + '</brands>

<subCats>' + (SELECT 1 as Tag, NULL as Parent, string [subCatID!1] FROM dbo.f_ConvertStringList_to_Table(@.subCatList) SubCats FOR XML EXPLICIT) + '</subCats>

<keywords>' + @.keywordSearch + '</keywords>

<priceFrom>' + CONVERT(varchar(10),@.priceFrom) + '</priceFrom>

<priceTo>' + CONVERT(varchar(10),@.priceTo) + '</priceTo>

<hiRes>' + CONVERT(varchar(10),@.bHiResImg) + '</hiRes>

<source>' + @.source + '</source>

</Search>

</AuditMsg>'

EXEC dbo.usp_SendAuditData @.AuditMsg

--SELECT @.AuditMsg

END

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

ALTER PROCEDURE [dbo].[usp_SendAuditData]

(

@.AuditedData XML

)

AS

BEGIN

BEGIN TRY

DECLARE @.dlgId UNIQUEIDENTIFIER

-- Begin the dialog, either with existing or new Id

BEGIN DIALOG @.dlgId

FROM SERVICE [//Audit/DataSender]

TO SERVICE '//Audit/DataWriter',

'X1X1X1X1-X1X1-X1X1-X1X1-X1X1X1X1X1X1'

ON CONTRACT [//Audit/Contract]

WITH ENCRYPTION = OFF;

;SEND ON CONVERSATION @.dlgId

MESSAGE TYPE [//Audit/Message] (@.AuditedData)

END TRY

END

I have stripped out a ton of code that doesn't really pertain, but this is basically what i'm doing.

|||

you know... that is the coolest GUID i've seen in a while!

well if a temp table is created then you could select from that temp table.

for temp tabel scopes read this post of mine:

http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx

you can also use a global temp table with a guid for name to avoid problems.

First Service Broker Attempt, Prajdic''s Example, Error: "queue has been disabled"

I am using the Centralized Asynchronous Auditing with Service Broker article example to set up my first Service Broker attempt. We want to start logging search criteria and search results for our product search page. We wanted it to be asynchronous and be stored in another dbase, this seemed like the perfect example.

I modified the example above to save into an Audit table we created and to read a custom message that I generated the XML for. I'm pretty certain that should all work. However, I didn't change much else but I can't get the message to send.

This is the error I'm getting in profiler:

This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742.

I am sending from one database to another within the same SQL server instance. Here are the profiler details

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry
Broker:Conversation Group Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query Larry
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query Larry
Broker:Message Classify Microsoft SQL Server Management Studio - Query Larry
Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Broker:Message Classify

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Remote Message Acknowledgement

Broker:Message Classify

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

Broker:Message Undeliverable This message was dropped because it could not be dispatched on time. State: 2 sa

When I run SELECT * FROM sys.transmission_queue I get this in the transmission_status:

"One or more messages could not be delivered to the local service targeted by this dialog."

I'm hoping someone can point me in the right direciton, thanks.

Larry Grady wrote:

Broker:Message Undeliverable This message could not be delivered because the destination queue has been disabled. Queue ID: 197575742. Microsoft SQL Server Management Studio - Query Larry APP1\Larry

Enable the destination queue using ALTER QUEUE [<queuename>] WITH STATUS = ON; During development queues often become disabled as a result of poison message prevention mechanism noticing rollbacks, see http://technet.microsoft.com/en-us/library/ms171592.aspx

|||

Ok, so it looks like the problem is before this. The real question is why is my queue being disabled. Because when I alter the queues to have WITH STATUS=ON or if I delete teh queues and services and recreate, when I run it the first time, my queue gets disabled. I'm not sure why, can't seem to find a good error message.

Here is profiler on that first run

SQL:BatchStarting

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Conversation Group Microsoft SQL Server Management Studio - Query

Broker:Conversation STARTED_OUTBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Message Classify Microsoft SQL Server Management Studio - Query

Broker:Conversation Group Microsoft SQL Server Management Studio - Query
Broker:Conversation STARTED_INBOUND Microsoft SQL Server Management Studio - Query
Broker:Conversation CONVERSING Microsoft SQL Server Management Studio - Query
Broker:Activation Microsoft SQL Server Management Studio - Query
SQL:BatchCompleted

EXEC dbo.usp_SendAuditData @.X Microsoft SQL Server Management Studio - Query sa
Broker:Queue Disabled
Broker:Activation

I get no results when I run SELECT * FROM sys.transmission_queue

Any idea why my que is disabling or where i can get a better message letting me know what's going on. This is my first attempt that this so it could be something simple I'm missing.

I used that original example and only changed the send and receive stored procedures and dbase names. No other administration was done.

|||Your activated procedure is rolling back and causing the queue to be disabled. Check ERRORLOG for error messages from the activated procedure. Turn off activation and run the procedure manually to catch it's output and debug it.|||

Hey!

In the future if you have any problems you're welcome to post the error in the comments section of that article because i don't really check here so often. I'm practicaly online all the time on SQLTeam during the work day so i'd also be able to answer any question you might have.

but as i see it Remus has it handled pretty well around here so no worries Smile

Mladen

|||

Thanks, these posts helped a lot.


I had changed the XML structure and the audit table/insert from the article to meet my biz needs and as a result I wasn't querying the msgBody correctly. However, I had no idea why my queue was disabled when I ran my example. It seemed more like an administration or permission error to me, so that's what I was concentrating on. It wasn't until I started stepping through, running pieces of the sprocs on their own that I found it.

But there wasn't any kind of informative error letting me know what the problem was on the target side. I think perhaps I need to institute the same kind of error handling that is in the initiating sproc into the targe sproc. Then if there is a logic error I can have some kind of information about it.

It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

Anyway, I have my basic example working and it seems to work great. Great example articles, thanks.

|||

Larry Grady wrote:


It scares me a little that if there is some unexpected data or formatting problem that my queues will just shut down.

In production you should monitor queues using event notifications for QUEUE_DISABLED event. This event is fired when a poison message disables a queue and you can react to the event (eg. notify the site administrator)|||

also in my example the error that causes the activation proc to rollback gets saved in the AuditErrors table.

you might want to check there for troubleshooting.

|||

My project is moving along nicely. I have my queues working properly and i'm writing data to my audit tables.

I have one more issue, although it's not directly SSB related, it is part of this project.

My main stored procedure is a product search. For each product search we have to save the Criteria that was used and then we have to save the products that were returned. The stored procedure itself is a really long and complicated proc that builds a dynamic sql string. Then at the end it executes it.


The way i ahve it working now

..... Process to build @.SQLString.....

EXEC(@.SQLString)

This returns my search results. Now i've added after it my initiator query. This query creates the AuditMsg in XML and loads it into a message which is que'd and sent to my target database where this data is inserted into an audit table.

EXEC usp_SendSearchAudit @.userID,@.brandID,....other criteria....., @.source

This is where i'm a little stuck. I need to then take the output, the actual records that are returned, and store 3 of the returned fields into an audit table. The results can be anywhere from a few records to a couple thousand.

I was thinking of INSERTING into a temp table and then sending that and doing a SELECT FOR XML to send to the audit table and then doing a SELECT @.tempResults to return from the main stored procedure. I don't know if that's really teh best way to do this. Anyone have any suggestions. I'm kind of struggling with the right way to do this. A few lines of pseudo code may go a long way. Thanks.

|||

i'm not quite sure i understand what you're trying to do...

could you post some sample code or pseudo code?

|||

Here is my initial search query (actually much of the dyamic part is stripped out because it doens't apply to the problem).

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

ALTER PROCEDURE [dbo].[spResults_Select]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.priceFrom real,

@.priceTo real,

[MORE CRITERIA]

@.bHiResImg int

)

AS

BEGIN

[LOTS OF CODE HERE BUILDING SQL STRING. Actually a TEMP table is build and then we select off of that temp table, it's very complicated. We plan on optimizing later but for now it is what it is]

[the string is @.SelectSQL]

EXEC(@.SelectSQL)

[This is where the original stored procedure ended. This EXEC line returns the search results back to the Search form]

[New Code: This stored procedure is an initiator query that takes the parameters, formulates it into XML, creates a messages and send it to SSB. This is for the search criteriea, this is working]

EXEC usp_SendSearchAudit

@.userID=@.userID,

@.brandList=@.brandList,

@.subCatList=@.subCatList,

@.keywordSearch=@.keywordSearch,

@.priceFrom=@.priceFrom,

@.priceTo=@.priceTo,

@.bHiResImg=@.bHiResImg,

@.source=@.source

[This is where I am stuck. EXEC(@.SelectSQL) returns a bunch of records to the searchresults object. However, I need to take those same records and extract the Product_ID from each and save it to the audit tables in teh other database. I am going to create XML object out of it, create a message, send it to SSB).

Something like

EXEC ups_SendSearchResultsAudit

[parameters]

Or, maybe It would all be a part of the usp_SendSearchAudit above, that I would pass a TABLE parameter into that stored procedure?

END

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

ALTER PROCEDURE [dbo].[usp_SendSearchAudit]

(

@.userID varchar(36),

@.brandList varchar(MAX),

@.subCatList varchar(MAX),

@.keywordSearch varchar(2000),

@.priceFrom real,

@.priceTo real,

@.bHiResImg int,

@.source varchar(10)

)

AS

BEGIN

DECLARE @.AuditMsg XML

SELECT @.AuditMsg = '<AuditMsg MsgType="Search">

<Search>

<userID>' + @.userID + '</userID>

<brands>' + (SELECT 1 as Tag, NULL as Parent, gID [brandID!1] FROM dbo.f_ConvertGuidList_to_Table(@.brandList) Brands FOR XML EXPLICIT) + '</brands>

<subCats>' + (SELECT 1 as Tag, NULL as Parent, string [subCatID!1] FROM dbo.f_ConvertStringList_to_Table(@.subCatList) SubCats FOR XML EXPLICIT) + '</subCats>

<keywords>' + @.keywordSearch + '</keywords>

<priceFrom>' + CONVERT(varchar(10),@.priceFrom) + '</priceFrom>

<priceTo>' + CONVERT(varchar(10),@.priceTo) + '</priceTo>

<hiRes>' + CONVERT(varchar(10),@.bHiResImg) + '</hiRes>

<source>' + @.source + '</source>

</Search>

</AuditMsg>'

EXEC dbo.usp_SendAuditData @.AuditMsg

--SELECT @.AuditMsg

END

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

Here is the query that is called from search results, it creates the xml and passes it into the initiator query

ALTER PROCEDURE [dbo].[usp_SendAuditData]

(

@.AuditedData XML

)

AS

BEGIN

BEGIN TRY

DECLARE @.dlgId UNIQUEIDENTIFIER

-- Begin the dialog, either with existing or new Id

BEGIN DIALOG @.dlgId

FROM SERVICE [//Audit/DataSender]

TO SERVICE '//Audit/DataWriter',

'X1X1X1X1-X1X1-X1X1-X1X1-X1X1X1X1X1X1'

ON CONTRACT [//Audit/Contract]

WITH ENCRYPTION = OFF;

;SEND ON CONVERSATION @.dlgId

MESSAGE TYPE [//Audit/Message] (@.AuditedData)

END TRY

END

I have stripped out a ton of code that doesn't really pertain, but this is basically what i'm doing.

|||

you know... that is the coolest GUID i've seen in a while!

well if a temp table is created then you could select from that temp table.

for temp tabel scopes read this post of mine:

http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx

you can also use a global temp table with a guid for name to avoid problems.