2009-02-22 11 views
5

Poprosiłem kilka osób, dlaczego używanie xml jako parametru w procedurze przechowywanej nie działa i wszyscy mówili, że tak właśnie jest. Nie mogę tego uwierzyć.C#/SQL - Co jest nie tak z SqlDbType.Xml w procedurach?

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

To gdzie kompilator zwróci błąd i nie można użyć nvarchar beacouse to limiteed do 4k śpiewa. XML byłby idealny, ponieważ może mieć 2 gigigi.

W jaki sposób inne SqlDbTypes działają dobrze i ten jeden retruns błąd?

*

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

*

+0

może być dobrym rozwiązaniem, aby dołączyć błąd do wiadomości. –

+0

Zakładam, że używasz co najmniej SQL2005 i że twoja kolumna jest zadeklarowana jako typ danych XML? – GregD

+0

jeśli używasz programu SQL Server 2005 lub nowszego, istnieje większy limit wielkości łańcuchów znaków NVARCHAR. Zobacz słowo kluczowe MAX - http://msdn.microsoft.com/en-us/library/ms186939.aspx - MAX wskazuje, że maksymalna długość dla NVARCHAR wynosi 1 073 747 822 –

Odpowiedz

13

To działa. Będziesz musiał ustawić wartość jako SqlXml, a nie ciąg znaków, ale można to zrobić. Wyobraź sobie taką tabelę:

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

a sproc:

CREATE PROCEDURE XmlTest_Insert 
(
    @XmlText xml 
) 
AS 

INSERT INTO XmlTest (XmlText) 
VALUES (@XmlText) 

Teraz obraz aplikację konsoli, który wygląda tak:

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!

Dokonano tego w Visual Studio 2008 (.NET 3.5), ale jestem dość pewny, że powinien działać również w Visual Studio 2005 (2.0 Framework).

+0

Twój przykład działa poprawnie, jak powinien, , ale kiedy wypróbuję go w mojej aplikacji CF 3.5, ciągle powtarza, że ​​SqlDbType.Xml - "Podany argument był poza zakresem prawidłowych wartości. Nazwa parametru: @xmldoc: Nieprawidłowe wyliczenie SqlDbType wartość: 25 "<- Wygląda jak enum Xml dla SqlDbType nie istnieje – Jacob

+1

Nie wiedziałem, że to Compact Framework. Zanim zmienię ćwiczenie, będę musiał przyjrzeć się regułom CF. Jest to podzbiór funkcjonalności w pełnym .NET Framework. –

0

Zamiast metody Add, spróbuj użyć AddWithValue gdzie nie trzeba określić typ tylko nazwę i wartość. O ile nie używasz innego kierunku do wprowadzania?

+0

I ' próbowałem tego, ale dało mi to wskazówkę. Podczas debugowania zauważyłem, że sądzi on, że wartość jest NVarChar, więc mój parametr xml jest w formacie wrongo, używam: data.Document.ToString(), gdzie dane to XDocument, może potrzebuje on dokumentu z informacjami o stronie kodowej? – Jacob

+0

Zamiast używać metody .ToString() należy podać rzeczywisty obiekt, ponieważ AddWithValue oczekuje parametru tekstowego, ale wartości obiektu. Pomyślałabym, że wtedy dostarczając twój XDocument, wziąłby on format, lub jak mówisz, podaj stronę kodową. –

-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 powinieneś podać szczegółowe informacje na temat swojej odpowiedzi – netaholic

+0

@newaholic komentarze są już dodane –