Вопросы Delphi/BDE/SQL Links
Объект: SQL Server
Некоторые вопросы, с которыми мне пришлось столкнуться (некоторые из них могут быть решены в самых последних обновлениях и версиях Delphi/BDE/SQL Links):
- TStoredProc не может работать с SQL Server 6.0 и ODBC. Delphi передает дополнительный параметр для возвращаемого значения процедуры, который не может "переварить" SQL 6.0. Такая же проблема была и в 4.21, но 4.21 не имел проверку этих параметров. Для использования хранимых процедур вы должны использовать TQuery.
TStoredProc с SQL Links имел ошибку в параметрах строки, заключающуюся в неправильном заполнении максимальной длины управляющих символов. Это калечило хранимые данные и делало так, что результаты, получаемые с любым выражением WHERE и использованием такого параметра никогда не соответствовали ожидаемым и действительным.
TStoredProc не прозрачен между SQL Links и ODBC. Если вы создаете компонент TStoredProc при связи посредством SQL Links, и запустите приложение с использованием соединения ODBC, это работать не будет. Delphi создает два различных (и несовместимых) синтаксиса для возвращаемого значения процедуры. Вы не можете переключаться между SQL Links и ODBC (в любом направлении).
Из-за проблем TStoredProc, описанных выше (и поскольку нам необходимо иметь возможность работы приложений со множеством SQL-серверов), для вызова хранимых процедур мы используем TQuery. Я не могу узнать как мне получить значение выходного параметра от хранимой процедуры, используя TQuery. Соединения ODBC всегда возвращают Null. Соединения SQL Links также возвращают Null или ошибку синтаксиса процедуры. Borland же требует безукоризненной работы. Я надеюсь что это сделать все-же можно, только мне пока не сообщили как. Многие программисты говорят об аналогичных проблемах.
Соединения ODBC игнорируют базу данных, определенную в источнике данных ODBC и всегда подключаются к основной (мастер) базе данных. Если вы определяете базу данных по умолчанию для пользователей SQL Server, она *будет* подключаться. Это проблема, похоже, относится только к драйверам Microsoft ODBC и как с ними работает Delphi. Некоторые сообщают, что драйвер Intersolv работает правильно.
Вы не должны забывать сбрасывать все запросы перед началом нового. SQL Server не допускает множества курсоров в одном соединении с базой данных, так что, если вы начинаете с запроса, возвращающего установленный результат, вам необходимо убедиться, что приложение выбрало все строки (TQuery.Last) перед началом другого запроса. Или перед началом другого запроса не забывайте закрывать предыдущий (TQuery.Close). Если вы не сделаете этого, вы увидете "Connection is in use by another statement" (Соединение используется другим запросом) при вашем следующем запросе.
Тем не менее, если вы вызываете TQuery.Prepare перед запуском вашего запроса, TQuery.Close не закроет соединения. Убей не знаю почему. Я начал получать целую кучу ошибок "Connection is in use by another statement" там, где я закрыл запрос перед началом следующего. Я потратил пару часов прежде чем выяснил, что мой вызов Prepare аннулирует вызов TQuery.Close.
TQuery медленнен для создания себя, если у вас есть куча SQL-параметров в множестве строк в свойстве SQL. При использовании TQuery для вызова хранимых процедур вы могли бы в общем случае воспользоваться им примерно таким образом:
execute pb_creditapp_update( :iAPPLICATION_ID, :iCURUSER_ID, :iNAME, :iADDRESS, :iCITY, и т.д. для нескольких строк. TQuery требует несколько секунд, чтобы "заполнить себя". Дело в том, что для каждой SQL-строки, добавляемой к компоненту, TQuery уничтожает свой внутренний список параметров и полностью создает его вновь. Так что, если вы имеете 50 параметров в разных строках, TQuery 50 раз пересоздаст внутренний список параметров.
У меня были проблемы с использованием RAISERROR в качестве исключения в Delphi. Обычно это классно работает. Но если вы используете это в хранимой процедуре после того, как ваша хранимая процедура что-то сделала для установления результата (SELECT), то RAISERROR не возвращается в Delphi в виде исключения (или ODBC, или SQL Links). Visual Basic это "получает" как положено, поэтому я подразумеваю, что это какая-то проблема с BDE. Если вы используете RAISERROR перед любым запросом, который устанавливает результат, то это работает как надо. [000698]
Содержание раздела