Элементы управления источником данных и преобразование типов параметров - PullRequest
1 голос
/ 21 марта 2009



Q1 - В приведенном ниже примере кода среда выполнения преобразует значение между двумя несовместимые типы:

  <SelectParameters>
 <asp:Parameter Name="City" Type="Int32" />
 </SelectParameters>



protected void SqlDataSource2_Selecting(object sender,
       SqlDataSourceSelectingEventArgs e)
{e.Command.Parameters["@City"].Value = "100";}

Исключение, которое я получил:

«Преобразование не удалось при преобразовании значения nvarchar« Сиэтл »в тип данных int. »

A) Вышеуказанное исключение предполагает, что во время выполнения удалось преобразовать значение типа String в значение типа Int32, и, следовательно, исключение произошло на SqlServer ?!

B) Поскольку String и Int32 являются несовместимыми типами, почему время выполнения выполнить преобразование из String в Int32 в первую очередь?

Разве не факт, что мы имеем дело с несовместимыми типами, делает среда выполнения «понимает», что в приложении, скорее всего, есть ошибка, похожая на Компилятор «понимает», что имеет дело (в приведенном ниже коде) с двумя несовместимые типы:

String s = ”something”;
int i = (int)s; //error



2:

A) public void GetEmployee (int EmployeeID);

<asp:ObjectDataSource  SelectMethod=”GetEmployee” …>
  <SelectParameters>
    <asp:ControlParameter Name = ”EmployeeID” ...>
  </SelectParameters>


Если по какой-либо причине параметр EmployeeID равен NULL, ObjectDataSource преобразует ноль в ноль и передает его в качестве аргумента в GetEmployee () способ.

Почему среда выполнения делает такое преобразование? Не бросал исключение имеет больше смысла?

B) «Используйте свойство ConvertEmptyStringToNull, чтобы указать, пустое значение строки автоматически преобразуется в ноль, когда данные поле обновляется в источнике данных. »
Я не совсем понимаю полезность этого свойства. Почему бы пустая строка указывает на то, что мы хотим, чтобы null был вставлен в источник поле данных? Я предполагаю, что это поле данных имеет тип String? затем почему бы также не иметь ConvertZeroInt32ToNull и т. д.?

Q3:

<asp:SqlDataSource ID="sourceEmployees" runat="server"
     ProviderName="System.Data.SqlClient"
     ConnectionString="<%$ ConnectionStrings:Northwind %>"
     SelectCommand="SELECT EmployeeID, FirstName,LastName,
     Title, City FROM Employees WHERE City=@City">
         <SelectParameters>
             <asp:Parameter Name="City"/>
         </SelectParameters>
</asp:SqlDataSource> 

A) Я предполагаю, что когда вы не указываете, какой тип параметра Например, «Город», он автоматически имеет тип Object, что означает, что Позже может быть назначено значение любого типа. Таким образом, если «Город» позже (скажем, внутри обработчика событий SqlDataSource2_Selecting ()) присвоено значение неправильный тип, это неправильное назначение будет обнаружено только на Sql сервер, а не раньше (конечно, сервер Sql сообщит об этой ошибке вернуться на веб-сервер)?

B) Если мы создаем экземпляр SqlParameter типа NVarChar (20) и хотим чтобы передать этот параметр хранимой процедуре, Ado.net перейдет к хранимая процедура только значение этого параметра, или это будет также как-то сообщить процедуре точный тип этого параметра (который такое NVarChar (20))?

спасибо

Ответы [ 3 ]

2 голосов
/ 25 марта 2009

Это ошибка SQL Server. Вы столкнулись с проблемой типа данных .

Ключ здесь:

SELECT EmployeeID, FirstName,LastName, Title, City FROM Employees WHERE
City=@City --here exactly

Городская колонна nvarchar Параметр явно установлен в int

Сложив все это вместе, вы получите:

SELECT EmployeeID, FirstName,LastName, Title, City FROM Employees WHERE
City=100

По правилам предшествующего типа данных механизм базы данных пытается изменить все значения для City на «int». И терпит неудачу, конечно.

Для ваших очков, хотя:

  • Q1: та же проблема. Нигде вы не сказали SQL Server, что «100» должно быть строкой
  • Q2: пустая строка приводит к нулю в SQL. Отправьте dbnull.value, если вам нужен SQL null
  • Q3a. SQL не имеет типа данных объекта. Он смотрит на 100 и решает "int"
  • Q3B. Да, используйте сохраненный процесс и определите его правильно.

В целом, SQL Server ведет себя точно так, как рекламируется. В этом случае вы просто не предоставляете достаточно информации.

Редактировать: использование хранимых процедур

Вы сообщаете SQL, какой тип данных используется при добавлении параметра в коллекцию параметров. Вы определяете (и создаете) сохраненный процесс, чтобы иметь параметр nvarchar.

1 голос
/ 22 марта 2009

Я просто попробую ответить на ваш первый вопрос - «Преобразование не удалось при преобразовании значения nvarchar« Сиэтл »в тип данных int.»

Поскольку я не вижу нигде упомянутого "Сиэтла", я предполагаю, что эта ошибка на самом деле исходит от хранимой процедуры, которую вы вызываете - т.е. что бы вы ни использовали @City в процедуре, это проблема. Похоже, вместо того, чтобы делать что-то вроде «где CityID = @ City», вы делаете «где CityName = @ City» и жалуетесь, что не могут преобразовать одно из значений CityName («Сиэтл») целое число для сравнения с @ City.

0 голосов
/ 22 марта 2009

Я предполагаю, что эта ошибка на самом деле исходит от хранимой процедуры, которую вы вызываете - т.е. что бы вы ни использовали @City в процедуре, это проблема. Похоже, вместо того, чтобы делать что-то вроде «где CityID = @ City», вы делаете «где CityName = @ City» и жалуетесь, что не могут преобразовать одно из значений CityName («Сиэтл») целое число для сравнения с @ City.

Я специально использовал несовместимые типы только для того, чтобы донести свою точку зрения -> вот почему среда выполнения даже не пытается попытаться преобразовать значение из одного несовместимого типа в другой, поскольку тот факт, что пользователь присвоил строку переменной типа integer, предполагает, что это, скорее всего, ошибка, а не то, что пользователь сделал сознательно »?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...