C#/SQL - Cosa c'è di sbagliato con SqlDbType.Xml nelle procedure?


5

Ho chiesto a poche persone perché l'uso di xml come parametro nella stored procedure non funzioni e tutti hanno detto, è proprio così. Non posso crederlo.

command.Parameters.Add("@xmldoc", SqlDbType.Xml); 

Ecco dove compilatore restituisce un errore e non posso utilizzare nvarchar beacouse è limiteed a 4k canta. XML sarebbe perfetto in quanto può essere grande 2gigs.

Come mai altri SqlDbTypes funzionano correttamente e questo ritorna a errori?

*

Error: Specified argument was out of the range of valid values. Parameter name: @xmldoc: Invalid SqlDbType enumeration value: 25.

*

  0

potrebbe essere utile allegare l'eventuale errore nel post. 22 feb. 092009-02-22 13:32:34

  0

Suppongo che tu stia utilizzando almeno SQL2005 e che la tua colonna sia dichiarata come un tipo di dati XML? 22 feb. 092009-02-22 13:35:36

  0

se si utilizza SQL Server 2005 in poi, esiste un limite maggiore alla dimensione delle stringhe NVARCHAR. Vedere la parola chiave MAX - http://msdn.microsoft.com/en-us/library/ms186939.aspx - MAX indica che la lunghezza massima per NVARCHAR è 1.073.741.822 22 feb. 092009-02-22 13:37:59

  0

Che aspetto ha il tuo parametro XML e come lo stai costruendo? 22 feb. 092009-02-22 13:50:07

  0

Questo articolo potrebbe essere di interesse - http://dotnet.sys-con.com/node/406637 - tutto il codice è disponibile tramite i collegamenti ipertestuali 22 feb. 092009-02-22 13:51:33

  0

@GregD - sql2005; non hanno bisogno di colonne xml, stored procedure process xml e inserire valori in culum (testato e funziona bene). @Russ Cam - Stai parlando di lato sql, per C# max è 4k. Ho provato questo. 22 feb. 092009-02-22 13:53:28

  0

Con quale versione del framework si sta tentando di compilare? SqlDatatype.Xml non esiste in .NET 1.1. 22 feb. 092009-02-22 13:54:14

  0

Se si tratta di un progetto ASP.NET, andare nelle impostazioni di IIS e verificare che si stia utilizzando il runtime corretto. 22 feb. 092009-02-22 13:56:20

  0

Compact Framewrok 3.5 22 feb. 092009-02-22 13:57:31

  0

@ Jacob- Ho scritto un esempio di app console C# l'altro giorno per dimostrare a un collega che è possibile passare una stringa NVARCHAR di lunghezza superiore a 4000 in una stored procedure. Pertanto, sono fermamente convinto che tu possa farlo. È necessario selezionare il tipo CLR corretto da associare al tipo SQL NVARCHAR (MAX) 22 feb. 092009-02-22 14:00:07

  0

Qual è il tipo dell'oggetto comando? 22 feb. 092009-02-22 14:01:37

  0

È possibile utilizzare il metodo SqlCommand.Parameters.AddWithValue, che a mio avviso lascia il framework per dedurre il tipo di dati del parametro 22 feb. 092009-02-22 14:05:04

  0

Se si utilizza SqlCommand.Parameters.Aggiungi metodo, quindi credo che il corretto SQLDbtype da utilizzare per NVARCHAR (MAX) sia NTEXT 22 feb. 092009-02-22 14:15:12

  0

Fondamentalmente, i più recenti VARCHAR (MAX), NVARCHAR (MAX) e VARBINARY (MAX) mappati a SQLDBTypes TEXT, NTEXT e IMAGE, rispettivamente 22 feb. 092009-02-22 14:19:19

13

Funziona. Dovrai impostare il valore come SqlXml e non una stringa, ma può essere fatto. Immaginate questa tabella:

CREATE TABLE XmlTest 
(
    [XmlTestId] [int] identity(1,1) primary key, 
    [XmlText] [xml] NOT NULL 
) 

E lo sproc:

CREATE PROCEDURE XmlTest_Insert 
(
    @XmlText xml 
) 
AS 

INSERT INTO XmlTest (XmlText) 
VALUES (@XmlText) 

Ora, immaginate un'applicazione console che assomiglia a questo:

using System.Data.SqlClient; 
using System.Data; 
using System.Data.SqlTypes; 
using System.Xml; 

namespace TestConsole 
{ 
    class Program 
    { 

     static void Main(string[] args) 
     { 
      string xmlDoc = "<root><el1>Nothing</el1></root>"; 
      string connString = "server=(local);database=IntroDB;UID=sa;PWD=pwd"; 
      SqlConnection conn = new SqlConnection(connString); 
      SqlCommand cmd = new SqlCommand("XmlTest_Insert", conn); 
      cmd.CommandType = CommandType.StoredProcedure; 
      SqlParameter param = new SqlParameter("@XmlText", SqlDbType.Xml); 
      param.Value = new SqlXml(new XmlTextReader(xmlDoc 
          , XmlNodeType.Document, null)); 
      cmd.Parameters.Add(param); 

      conn.Open(); 
      cmd.ExecuteNonQuery(); 
      conn.Dispose(); 
     } 
    } 
} 

Bingo!

Questo è stato eseguito in Visual Studio 2008 (.NET 3.5), ma sono abbastanza sicuro che dovrebbe funzionare anche in Visual Studio 2005 (2.0 Framework).

  0

L'esempio funziona bene come dovrebbe, anche se quando lo provo sulla mia app CF 3.5 continua a dire che SqlDbType.Xml - "L'argomento specificato era fuori dall'intervallo di valori validi. Nome parametro: @xmldoc: Enumerazione SqlDbType non valida value: 25 "<- Sembra che enum Xml per SqlDbType non esiste 22 feb. 092009-02-22 16:33:18

+1

Non mi ero reso conto che fosse Compact Framework. Dovrei guardare le regole della FC prima di modificare l'esercizio. È un sottoinsieme della funzionalità in .NET Framework completo. 25 feb. 092009-02-25 16:31:37


0

Invece di utilizzare il metodo Add, provare a utilizzare AddWithValue in cui non è necessario specificare solo il nome e il valore del tipo. A meno che non si stia utilizzando una direzione diversa per l'input?

  0

I ' Ci ho provato, ma mi ha dato un indizio. Durante il debug ho notato che pensa che il valore sia NVarChar, quindi il mio parametro xml è nel formato sbagliato, io uso: data.Document.ToString(), dove i dati sono XDocument, forse ha bisogno del doc con le informazioni sulla codepage? 22 feb. 092009-02-22 14:15:48

  0

Invece di usare il metodo .ToString() prova a fornire l'oggetto stesso, poiché AddWithValue si aspetta un parametro stringa ma un valore oggetto. Avrei pensato che quindi fornire il tuo XDocument avrebbe raccolto nel formato, o come si dice fornire una codepage. 22 feb. 092009-02-22 14:32:33


-2
 
//Create The StringWriter Object 

var stringWriter = new System.IO.StringWriter(); 

//Create XmlSerializer Object for the serialization, 
RequestUpdateRBCustomerExternal is the Class of which type having all the values 

var serializer = new XmlSerializer(typeof(RequestUpdateRBCustomerExternal)); 

//request is of type RequestUpdateRBCustomerExternal 

serializer.Serialize(stringWriter, request); 

SqlXml xml = new SqlXml(new XmlTextReader(stringWriter.ToString(), XmlNodeType.Document, null)); 

cmd.CommandText ="insert into SAPDataTracking values('"+DateTime.Now+"','"+xml.Value+"')"; 
  0

IMO dovresti fornire i dettagli sulla tua risposta 21 set. 152015-09-21 15:02:06

  0

@ i commenti nazionali sono già stati aggiunti 22 set. 152015-09-22 04:27:01