![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сюрприз при использовании ADO + MS SQL + пустой параметр ftString
И. Павел © (2010-08-31 11:26:00)Здравствуйте.
Наткнулся на странный результат выполнения запроса, с использованием пустого строкового параметра в MS SQL SERVER 2005. Вот такой код:
ADODS.Active := false;
ADODS.CommandText := 'SELECT … FROM USERLIST.dbo.UserInf WHERE login=:PLogin AND password= :PPassword';
ADODS.Parameters.ParseSQL(ADODS.CommandText, true);
ADODS.Parameters.ParamByName('PLogin').Value := login;
ADODS.Parameters.ParamByName('PPassword').Value := password;
ADODS.Open;
В случае если пароль пустой (т.е. password = ''), возникает ошибка (EOleException):
'The data types varchar and text are incompatible in the equal to operator'.
То есть SQL SERVER почему-то считает, что пустой параметр типа ftString имеет тип Text.
Эта же ошибка возникает, если вручную задавать DataType и Direction параметра.
Поле “password” имеет тип “varchar(50)”.
А если закомментировать строчку:
ADODS.Parameters.ParseSQL(ADODS.CommandText, true)
т.е. предоставить SQL Server и ADO подготавливать параметры самостоятельно, то все работает нормально, в том числе и при пустом пароле.
Методом тыка выяснил, что ошибка возникает из-за того, что при пустом пароле операция
ADODS.Parameters.ParamByName('PPassword').Value := '';
не меняет свойство Size для параметра, оставляя его равным -1. Код:
ADODS.Active := false;
ADODS.CommandText := 'SELECT … FROM USERLIST.dbo.UserInf WHERE login=:PLogin AND password= :PPassword';
ADODS.Parameters.ParseSQL(ADODS.CommandText, true);
ADODS.Parameters.ParamByName('PLogin').Value := login;
ADODS.Parameters.ParamByName('PPassword').Value := 1;
ADODS.Parameters.ParamByName('PPassword').Value := password;
ADODS.Open;
Работает. Но выглядит так себе, и, скорее всего, может вызвать еще какие-нибудь ошибки.
Подскажите, пожалуйста, как наиболее правильно работать с параметрами в ADODataSet и ADOCommand (ну и ADOQuery, т.к. в старых проектах я использовал его)? В частности: насколько правильно полагаться на автоматический “ParseSQL” и определение типа параметра? Если можно, то прямо пример, начиная от ADODS.Active := false.
PS: в access такой ошибки не возникает.
PPS: везет же мне на такие штуки… Максимальная отрицательная константа, проблема с параметрами в join в Access, время от времени не загружающийся реестр, теперь вот это… У всех так, или это у меня карма низкая?:)
Заранее спасибо.
Anatoly Podgoretsky (2010-08-31 12:57:00) [1]> И. Павел (31.08.2010 12:54:10) [10]
Но и в БДЕ он рекомендовался к применению только в редких случаях.
И. Павел (2010-08-31 12:54:00) [2]> ParseSQL имел смысл в БДЕ
Спасибо. Запомню на всякий случай. Хотя последний раз с БДЕ работал еще в институте.
И. Павел (2010-08-31 12:53:00) [3]> Если ошибки про несуществование параметра не возникает,
> то ессно писать именно так. На кой хрен еще раз парсить.
Спасибо. Тогда буду писать так.
Palladin (2010-08-31 12:52:00) [4]
> Если да, то буду теперь писать так.
Если ошибки про несуществование параметра не возникает, то ессно писать именно так. На кой хрен еще раз парсить.
Anatoly Podgoretsky (2010-08-31 12:52:00) [5]> И. Павел (31.08.2010 12:44:06) [6]
ParseSQL имел смысл в БДЕ
И. Павел (2010-08-31 12:44:00) [6]> Так чего же ты мучишься?
Просто часто встречаю ParseSQL в разных статьях и на форумах, вот и подумал, что лучше использовать его. А оказалось - что это привело к тому, что тип параметра не совпадает с DataType.
Подскажите, пожалуйста, создание запроса с параметрами таким образом правильно:
ADODS.Active := false;
ADODS.CommandText := 'SELECT … FROM USERLIST.dbo.UserInf WHERE login=:PLogin AND password= :PPassword';
ADODS.Parameters.ParamByName('PLogin').Value := login;
ADODS.Parameters.ParamByName('PPassword').Value := password;
ADODS.Open;
Если да, то буду теперь писать так.
> Этого нам не достаточно
Вот все, что я нашел по полю "password", если нужно что-то еще - напишите:
Name - password
Data Type - varchar
System Type - varchar
Primary key - False
Allow nulls - False
Is Computed - False
Computed Text -
Identity - False
Identity seed - 0
Identity increment - 0
Default Binding
Default Schema
Rule
Rule Schema
Length - 50
Collation - Cyrillic_General_CI_AS
Numeric precision - 0
Numeric scale - 0
XML Schema Namespace -
XML Schema Namespace schema
Not for replication - False
Full text - False
ANSI Padding Status - True
Anatoly Podgoretsky (2010-08-31 12:04:00) [7]
> Поле “password” имеет тип “varchar(50)”.
Этого нам не достаточно
> т.е. предоставить SQL Server и ADO подготавливать параметры
> самостоятельно, то все работает нормально, в том числе и
> при пустом пароле.
Так чего же ты мучишься?
И. Павел (2010-08-31 11:49:00) [8]
> у тебя скорее всего NVarChar тип поля в таблице
Я перепроверил - тип именно varchar(50).
> я после парсинга сам в ручную назначал DataType в ftString
> и потом присваивал значение
Код:
ADODS.Active := false;
ADODS.CommandText := 'SELECT login, password, cabinet, log_del, ReportType, type FROM USERLIST.dbo.UserInf WHERE login=:PLogin AND password= :PPassword';
ADODS.Parameters.ParseSQL(ADODS.CommandText, true);
ADODS.Parameters.ParamByName('PLogin').DataType := ftString;
ADODS.Parameters.ParamByName('PLogin').Value := login;
ADODS.Parameters.ParamByName('PPassword').DataType := ftString;
ADODS.Parameters.ParamByName('PPassword').Value := password;
ADODS.Open;
У меня возвращает ту же ошибку.
Я попробовал сменить тип поля "password" на text, ошибка приняла вид:
'The data types text and varchar are incompatible in the equal to operator'.
тоесть теперь параметр воспринимается как varchar :)
Palladin (2010-08-31 11:32:00) [9]у тебя скорее всего NVarChar тип поля в таблице
Palladin (2010-08-31 11:31:00) [10]
> То есть SQL SERVER почему-то считает, что пустой параметр
> типа ftString имеет тип Text.
он не ftString, выведи после
ADODS.Parameters.ParseSQL(ADODS.CommandText, true);
ADODS.Parameters.ParamByName('PLogin').DataType
я после парсинга сам в ручную назначал DataType в ftString и потом присваивал значение... есть такой косяк...
И. Павел (2010-08-31 11:27:00) [11]Извиняюсь, я опечатался. Не
> ADODS.Parameters.ParamByName('PPassword').Value := 1;
а
> ADODS.Parameters.ParamByName('PPassword').Size := 1;