Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
DB Engine
SQL ServerMSDESQL Server CE
Services
Analysis (Data Mining)Analysis (OLAP)DTSIntegration ServicesNotification ServicesReporting Services
Programming
CLRConnectivitySQLXML
Other Technologies
ClusteringEnglish QueryFull-Text SearchReplicationService Broker
General
Data WarehousingPerformanceSecuritySetupSQL Server ToolsOther SQL Server Topics
DirectoryUser Groups
Related Topics
MS AccessOther DB ProductsMS Server Products.NET DevelopmentVB DevelopmentJava DevelopmentMore Topics ...

SQL Server Forum / Other Technologies / Service Broker / January 2007

Tip: Looking for answers? Try searching our database.

Conversion of characters from XML to target collation impossible

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Andrew Robinson - 10 Jan 2007 07:19 GMT
I have successfully setup Login Auditing using Service Broker, but have an
application that tries to login using invalid characters (猀愀). 2 empty
squares.

I have been unsuccessful in trapping this as an error in my Stored Proc
which is activated on my Queue, and as a result and as expected, it tries 5
times to unsuccessfully remove the message from the queue with the error:

The activated proc [dbo].[usp_Logging_20070108] running on queue
SQLAuditing.dbo.AuditLogonQueue output the following:  'Conversion of one or
more characters from XML to target collation impossible'

and subsequently disables the queue.

I am using the BOL trackmessage stored proc for error trapping, but this
needs @@error <>0 which it does not seem to be incremented.

I need help with my error handling.   If you need to see the sp, let me know.
Andrew Robinson - 10 Jan 2007 08:41 GMT
I thought I would add the sp anyway...

CREATE PROCEDURE [dbo].[usp_Audit_Logins]
AS
SET NOCOUNT ON
DECLARE     @message_body XML,
           @message_type_name NVARCHAR(256),
           @dialog UNIQUEIDENTIFIER;

WHILE (1 = 1)
BEGIN
    BEGIN TRANSACTION
        SAVE TRANSACTION UndoReceive ;
   -- Receive the next available message

   WAITFOR (
        RECEIVE TOP(1)
           @message_type_name=message_type_name,
           @message_body=message_body,
           @dialog = conversation_handle
           FROM AuditLogonQueue
            ), TIMEOUT 2000

--Rollback and exit if no messages were found
    IF (@@ROWCOUNT = 0)
       BEGIN
           ROLLBACK TRANSACTION
           BREAK
       END
   
 --End conversation of end dialog message
   IF (@message_type_name =
'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
   BEGIN
       PRINT 'End Dialog received for dialog # ' + cast(@dialog as
nvarchar(40))
       END CONVERSATION @dialog
        ROLLBACK TRANSACTION
   END
 ELSE
   BEGIN
    DECLARE @DatabaseId VARCHAR(50)
   
    SET @DatabaseId =
CAST(@message_body.query('/EVENT_INSTANCE/DatabaseID/text()') AS VARCHAR(50))
   
    INSERT INTO AuditLogins(EventTime, EventType, LoginName, HostName,
NTUserName, NTDomainName,[Database],XMLEvent,
   EventMonth, EventYear)
    VALUES
    (
        CAST(CAST(@message_body.query('/EVENT_INSTANCE/PostTime/text()') AS
VARCHAR(64)) AS DATETIME),
        CAST(@message_body.query('/EVENT_INSTANCE/EventType/text()') AS
VARCHAR(100)),
        CAST(@message_body.query('/EVENT_INSTANCE/LoginName/text()') AS
VARCHAR(100)),
        CAST(@message_body.query('/EVENT_INSTANCE/HostName/text()') AS
VARCHAR(100)),
        CAST(@message_body.query('/EVENT_INSTANCE/NTUserName/text()') AS
VARCHAR(100)),
        CAST(@message_body.query('/EVENT_INSTANCE/NTDomainName/text()') AS
VARCHAR(100)),
        CASE ISNULL(@DatabaseId,'Unknown')
        WHEN 'Unknown' THEN 'Unknown'
        ELSE DB_NAME(@DatabaseId)
        END,
        @message_body,
       
month(CAST(CAST(@message_body.query('/EVENT_INSTANCE/PostTime/text()') AS
VARCHAR(64)) AS DATETIME)),
       
year(CAST(CAST(@message_body.query('/EVENT_INSTANCE/PostTime/text()') AS
VARCHAR(64)) AS DATETIME))
    )

    if @@error <> 0
            BEGIN
              ROLLBACK TRANSACTION UndoReceive ;
              EXEC TrackMessage @dialog ;
            END ;
          --END
           ELSE
            BEGIN
              EXEC dbo.ClearMessageTracking
                @dialog ;
            END
    END
    COMMIT TRANSACTION
END
Roger Wolter[MSFT] - 10 Jan 2007 16:53 GMT
The key here is to rollback and retry only if there's some hope that trying
again will result in success.  Your logic does a rollback on any error so
anything that is caused by the input data will always disable the queue.
Things like deadlocks, disk errors, out-of-space conditions are worth
retrying but any kind of permanent error is not.  Try-catch also makes error
handling easier to write.  Here's the message processing part of a sample I
use:

WHILE (1 = 1)

BEGIN

BEGIN TRANSACTION

-- Receive the next available message

WAITFOR (

RECEIVE top(1) -- just handle one message at a time

@MessageType=message_type_name, --the type of message received

@MessageBody=message_body, -- the message contents

@ConversationHandle = conversation_handle -- the identifier of the dialog
this message was received on

FROM [ISBNLookupTargetQueue]

), TIMEOUT 1000 -- if the queue is empty for five seconds, give up and go
away

-- This timeout should be tuned based on how expensive it is to startup up
the stored procedure

-- If we didn't get anything, the queue is empty so bail out

if (@@ROWCOUNT = 0)

BEGIN

ROLLBACK TRANSACTION

BREAK

END

SAVE TRANSACTION AFTERREAD

IF (@MessageType =
'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')

BEGIN

-- When we receive an End Dialog, we need to end also.

END CONVERSATION @ConversationHandle

END

ELSE

IF (@MessageType = 'http://schemas.microsoft.com/SQL/ServiceBroker/Error')

BEGIN

-- Handle the error here. Maybe log it or send a notification to someone.

-- If there are still messages in the queue you may or may not want to
process them.

-- If work has already been done and committed as part of this dialog, you

-- may have to issue compensating transactions to undo it.

-- At this point the other end can't receive or send messages so once the
error is

-- handled the only thing to do is end our end of the dialog also.

END CONVERSATION @ConversationHandle

END

ELSE

IF (@MessageType = 'ISBNLookupRequest')

BEGIN

BEGIN TRY

Print 'In try'

insert into tst values (10)

END CONVERSATION @conversationHandle

END TRY

BEGIN CATCH

Print 'In Catch'

-- Check for transient errors. The numbers depend on what you're doing

-- I included some of the more obvious ones here

IF error_number() IN (580,596,601,701,708,802,844,845,

846, 847, 921,922, 923, 1121, 2502, 3967,

3984, 3985, 1205, 2755, 3635, 3928, 17884,

1203, 1221, 1807, 6292, 20041 )

BEGIN

ROLLBACK TRANSACTION

CONTINUE

END

ELSE BEGIN

ROLLBACK TRANSACTION AFTERREAD

INSERT INTO err VALUES (getdate(), error_number(), error_message())

END

END CATCH

end -- process message

Signature

This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm

>I thought I would add the sp anyway...
>
[quoted text clipped - 87 lines]
> COMMIT TRANSACTION
> END
Andrew Robinson - 11 Jan 2007 09:54 GMT
Thank you very much for your help Roger.

May I ask one more question, when the queue does eventually get disabled,
what are the various ways in which one can re-activate it, apart from
dropping and recreating all the various queues, routes, etc?
Roger Wolter[MSFT] - 11 Jan 2007 15:38 GMT
ALTER QUEUE xxx WITH STATUS = ON

Signature

This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm

> Thank you very much for your help Roger.
>
> May I ask one more question, when the queue does eventually get disabled,
> what are the various ways in which one can re-activate it, apart from
> dropping and recreating all the various queues, routes, etc?
Andrew Robinson - 11 Jan 2007 15:51 GMT
Thanks again Roger.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.