C#/SQL - Что не так с SqlDbType.Xml в процедурах?


5

Я спросил несколько человек, почему использование xml в качестве параметра хранимой процедуры не работает, и все сказали, что так оно и есть. Я не могу этого поверить.

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

Вот где компилятор возвращает ошибку, и я не могу использовать NVARCHAR beacouse это limiteed к 4k поет. XML был бы идеальным, так как он может быть большим.

Почему другие SqlDbTypes работают хорошо, и этот один извлекает ошибку?

*

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

*

  0

может быть полезно приложить ошибку, если таковой имеется в сообщении. 22 фев. 092009-02-22 13:32:34

  0

Я предполагаю, что вы используете по крайней мере SQL2005 и что ваш столбец объявлен как тип данных XML? 22 фев. 092009-02-22 13:35:36

  0

, если вы используете SQL Server 2005 и больше, размер строк NVARCHAR больше. См. Ключевое слово MAX - http://msdn.microsoft.com/en-us/library/ms186939.aspx - MAX указывает, что максимальная длина для NVARCHAR равна 1,073,741,822 22 фев. 092009-02-22 13:37:59

  0

. Как выглядит ваш XML-параметр и как его построить? 22 фев. 092009-02-22 13:50:07

  0

Эта статья может представлять интерес - http://dotnet.sys-con.com/node/406637 - весь код доступен через гиперссылки 22 фев. 092009-02-22 13:51:33

  0

@GregD - sql2005 действительно; не нужны столбцы xml, процедура xml хранимой процедуры и вставлять значения в кулум (проверены и работают нормально). @ Russ Cam - Вы говорите о стороне sql, поскольку C# max - 4k. Пробовал это. 22 фев. 092009-02-22 13:53:28

  0

Какую версию рамки вы пытаетесь скомпилировать? SqlDatatype.Xml не существует в .NET 1.1. 22 фев. 092009-02-22 13:54:14

  0

Если это проект ASP.NET, войдите в настройки IIS и убедитесь, что вы работаете в правильной среде выполнения. 22 фев. 092009-02-22 13:56:20

  0

Compact Framewrok 3.5 22 фев. 092009-02-22 13:57:31

  0

@ Jacob- Я написал пример приложения консоли C# на днях, чтобы продемонстрировать коллеге, что вы можете передать строку длиной NVARCHAR длиной более 4000 длиной в хранимую процедуру. Поэтому я категоричен, что вы можете это сделать. Вам нужно выбрать правильный тип CLR для сопоставления с типом SQL-типа NVARCHAR (MAX) 22 фев. 092009-02-22 14:00:07

  0

Каков тип объекта команды? 22 фев. 092009-02-22 14:01:37

  0

Вы можете использовать метод SqlCommand.Parameters.AddWithValue, который, как мне кажется, оставляет рамки для вывода типа данных параметра 22 фев. 092009-02-22 14:05:04

  0

. Если вы используете SqlCommand.Parameters.Add method, то я считаю, что правильный SQLDbtype для использования в NVARCHAR (MAX) является NTEXT 22 фев. 092009-02-22 14:15:12

  0

В основном, новые VARCHAR (MAX), NVARCHAR (MAX) и VARBINARY (MAX) сопоставляются с SQLDBTypes TEXT, NTEXT и IMAGE, соответственно 22 фев. 092009-02-22 14:19:19

13

Это действительно работает. Вам нужно будет установить значение как SqlXml, а не строку, но это можно сделать. Представьте себе эту таблицу:

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

И в sproc:

CREATE PROCEDURE XmlTest_Insert 
(
    @XmlText xml 
) 
AS 

INSERT INTO XmlTest (XmlText) 
VALUES (@XmlText) 

Теперь представьте консольное приложение, которое выглядит следующим образом:

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(); 
     } 
    } 
} 

Бинго!

Это было сделано в Visual Studio 2008 (.NET 3.5), но я уверен, что он должен работать и в Visual Studio 2005 (2.0 Framework).

  0

В вашем примере работает absoloutle fine, как и должно быть, , хотя, когда я пытаюсь использовать его в приложении CF 3.5, он продолжает говорить, что SqlDbType.Xml - «Указанный аргумент вышел за пределы допустимых значений. Имя параметра: @xmldoc: Недопустимое перечисление SqlDbType value: 25 "<- похоже, что перечисление Xml для SqlDbType не существует 22 фев. 092009-02-22 16:33:18

+1

Я не понимал, что это Compact Framework. Я должен был бы рассмотреть правила CF перед изменением упражнения. Это подмножество функциональных возможностей в полной .NET Framework. 25 фев. 092009-02-25 16:31:37


0

Вместо того, чтобы использовать метод Add, попробуйте использовать AddWithValue, где вам не нужно указывать тип только имя и значение. Если вы не используете другое направление ввода?

  0

I ' Я попробовал это, но это дало мне ключ. Во время отладки я заметил, что он считает, что значение NVarChar, поэтому мой параметр xml находится в неправильном формате, я использую: data.Document.ToString(), где данные XDocument, может быть, ему нужен документ с информацией о кодовой странице? 22 фев. 092009-02-22 14:15:48

  0

Вместо использования метода .ToString() попробуйте предоставить сам фактический объект, так как AddWithValue ожидает строковый параметр, но значение объекта. Я бы подумал, что, предоставив свой XDocument, он заберет формат или, как вы сказали, предоставит кодовую страницу. 22 фев. 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 вы должны предоставить подробную информацию о вашем ответе 21 сен. 152015-09-21 15:02:06

  0

комментарии @netaholic добавлены уже 22 сен. 152015-09-22 04:27:01