Domanda

Ho impostare più SQL Service Broker code in un database, ma non ho visto questo problema prima. Un messaggio contenente XML viene convertito in quello che sembra essere per lo più i caratteri cinesi. Quando controllo la variabile che si memorizza il codice XML prima di metterlo nella coda dei messaggi posso vedere che è in inglese ed è formato ben XML. Quando seleziono dalla coda ricevo i caratteri cinesi. Questi caratteri sono anche ciò che ricevo quando mi tiro dalla coda con un programma esterno C #. Ciò che è strano è che se osservo la coda utilizzando DBArtisan vedo l'XML ben formato.

L'XML sotto quando collocato su una coda si trasforma in seguito caratteri cinesi

<?xml version="1.0" ?>
<Message>
  <MachineName>The Super Duper Machine</MachineName>
  <CollectionName>snl0013d</CollectionName>
  <Action>Install</Action>
  <EntryDateTime>Jul  9 2009  4:47PM</EntryDateTime>
</Message>

㼼浸敶獲潩㵮ㄢ〮•㸿਍†††䴼獥慳敧ാ
 †††㰠慍档湩乥浡㹥桔⁥畓数⁲畄数⁲慍档湩㱥䴯捡楨敮慎敭ാ
 †††㰠潃汬捥楴湯慎敭猾汮〰㌱㱤䌯汯敬瑣潩乮浡㹥਍
 ††††䄼瑣潩㹮湉瑳污㱬䄯瑣潩㹮
 ਍††††䔼瑮祲慄整楔敭䨾汵†‹〲㤰†㨵〱䵐⼼湅牴䑹瑡呥浩㹥਍
†††⼼敍獳条㹥

Di seguito è riportato il T-SQL che sto usando per mettere il messaggio sulla coda e selezionarlo.

declare @dialog_handle uniqueidentifier
       ,@msg varchar(max)
       ,@collection_name varchar(30)

set @collection_name = 'snl0013d'

set @msg =
N'<?xml version="1.0" ?>
  <Message>
    <MachineName>' + 'The Super Duper Machine' + '</MachineName>
    <CollectionName>' + @collection_name + '</CollectionName>
    <Action>' + 'Install' + '</Action>
    <EntryDateTime>' + CAST(getdate() AS VARCHAR(100)) + '</EntryDateTime>
  </Message>'

select @msg

set @dialog_handle = NEWID()
begin dialog conversation @dialog_handle
    from service [SAPP_QUEUE_ResponseService]
    to service 'SAPP_QUEUE_SubmitService'
    on contract [SAPP_CONTRACT_Contract]
    with encryption = off;

send on conversation @dialog_handle
  message type [SAPP_MSG_MessageType]
(
    @msg
);
end conversation @dialog_handle 
with cleanup

select message_body
      ,conversation_handle
      ,CONVERT(nvarchar(max), message_body) as msg
  from SAPP_QUEUE_SubmitQueue;
È stato utile?

Soluzione

Non so se questo è tutto, ma vedo che utilizza letterali nvarchar ma assegnando a VARCHAR variabili ...

Altri suggerimenti

OK, questa risposta è fuori tema, ma devo: si prega di non fare con service Broker. Il modello di inizio-send-end messaggio ha molti problemi, che vanno dal non essere in grado di guasti di risposte di errore al database di essere messo offline. Il seguito è causa di un bug in SSB (SQL Service Broker), ma ho visto accadere ed è causata da un incendio e dimenticare modello messaggio.

Oh, e un'altra cosa:. Non so che cosa è DBArtisan, ma vede il messaggio ASCII come valido, allora vuol dire che proietta la colonna message_body a varchar (max), questo è tutto

E dal momento che il mio post è già grande, mi permetta di praticare un po 'in codifica XML e SSB troppo. Come probabilmente sapete, SSB offre la convalida messaggio XML se si dichiara il tipo di messaggio [SAPP_MSG_MessageType] come VALIDATION = WELL_FORMED_XML. Ma ASCII e Unicode sono entrambi codifiche XML validi ed entrambi sono supportate da SSB. È possibile inviare un messaggio N '<someTag>somecontent</someTag>' e anche '<someTag>somecontent</someTag>', entrambi sono frammenti XML validi. È inoltre possibile aggiungere le istruzioni di elaborazione XML esplicite dichiarano la codifica, come <?xml version="1.0" encoding="utf-8"?> o N <?xml version="1.0" encoding="utf-16"?>. Tuttavia si corre il rischio di mismatching, come dichiarato N <?xml version="1.0" encoding="utf-8"?>, che in realtà è XML non valido (in quanto la codifica dichiarato non corrisponde alla codifica del documento). È possibile eseguire in tutti i tipi di molto sottile e difficile da risolvere i problemi di questo tipo. Questo è un perfetto esempio di problema che può causare il servizio di destinazione per rifiutare il messaggio e non riescono la finestra di dialogo con una risposta di validazione XML, che si sta andando a perdere a causa ... si sta facendo fuoco e dimentica:)

Nella mia pratica (ero uno dei membri del team di SQL servizio Broekr a MS) ho scoperto che il modo migliore per evitare problemi è quello di dichiarare le variabili che tengono il mandato (@msg) come tipo xml , non varchar nè nvarchar . Questo si prende cura di tutte le questioni e anche risponde correttamente la necessità e la presenza di un BOM nel vostro XML . Questo vale anche per i parametri di C # passati in, il miglior match è quello di utilizzare il SqlXml tipo e / o la .Data.SqlDbType.Xml valore enum.

Anche sul lato ricezione della coda (la vostra procedura attivata o processo che legge la coda di destinazione) il vostro dovrebbe gettare il corpo del messaggio di tipo XML, non a VARCHAR / nvarchar. E già che siamo in tema, assicurarsi che non si lanci durante il la ricevono, ma solo dopo la ricezione a causa del modo XML la gestione degli errori interagisce con l'attivazione .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top