Максимальная длина значений TSQLConnection.Params

Здравствуйте товарищи StackOverflowers,

В настоящее время я сталкиваюсь с ситуацией, когда кажется, что существует максимальная длина свойства базы данных объекта TSQLConnection в Delphi.

Когда я открываю соединение с моей базой данных, я получаю следующую ошибку, когда использую довольно длинное (154 символа) имя базы данных:

dbExpress Error: [0x0015]: Connection failed SQL Server Error: unrecognized database parameter block wrong version of database parameter block

Когда я перемещаю файл базы данных в другое место (и тем самым уменьшаю длину пути), он подключается к базе данных.

В настоящее время я использую инспектор объектов для установки свойств соединения объекта TSQLConnection.

В общем, мой вопрос сводится к следующему:

Имеет ли TSQLConnection максимальную длину для значений, установленных в свойстве Params? И если да, то какова максимальная длина этих значений?


person RFerwerda    schedule 19.02.2016    source источник
comment
TSQLConnections.Params равно TStrings, поэтому, если здесь есть ограничение, это ограничение TStrings. edn.embarcadero.com/article/30333   -  person Val Marinov    schedule 19.02.2016
comment
Вы отметили свой вопрос Interbase. Вы на самом деле спрашиваете о сервере Interbase или каком-то другом внутреннем сервере?   -  person MartynA    schedule 19.02.2016
comment
@MartynA Я работаю с межбазовым сервером.   -  person RFerwerda    schedule 19.02.2016
comment
Ах, хорошо, я был озадачен ошибкой SQL Server в сообщении об ошибке.   -  person MartynA    schedule 19.02.2016
comment
@MartynA Я согласен с тем, что сообщение об ошибке, которое я получаю, несколько расплывчато и не совсем объясняет.   -  person RFerwerda    schedule 19.02.2016
comment
Пожалуйста, не могли бы вы добавить к вашему q: а) версию Delphi b) версию Interbase c) содержимое DFM для вашего TSqlConnection d) точный код, который вы используете для открытия соединения, и любые значения Params, которые вы добавляете или изменяете в коде. Причина, по которой я спрашиваю, заключается в том, что, работая над своим ответом, я столкнулся с некоторым неустойчивым поведением, по-видимому, сервера IB, и хотел бы сравнить то, что вы делаете, с тем, что делаю я.   -  person MartynA    schedule 20.02.2016
comment
@MartynA Я использую Delphi 7 и Interbase XE. На данный момент, как описано в посте, задаю параметры соединения в проводнике объектов. Я также использую обозреватель объектов, чтобы установить для свойства connected значение true.   -  person RFerwerda    schedule 22.02.2016
comment
спасибо Неустойчивое поведение, о котором я упоминал, оказалось моим, а не программным обеспечением (!). Вы пробовали мой ответ в D7? Я не могу сам в данный момент, так как машина, на которой я установил ИБ для D7, сейчас находится в ремонте.   -  person MartynA    schedule 22.02.2016


Ответы (2)


Обновить

Я нашел два способа открыть копию Employee.Gdb в папке со 160-символьным именем ('abcdefghij0123456789' x 8).

Сначала я отредактировал файл DBXConnections.Ini и изменил параметр базы данных в разделе [IBConnection] на чтение

Database=localhost:D:\abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890\employee.gdb

Затем я могу успешно подключиться к нему, открыть Employee.Gdb и внести изменения в таблицу Customer. Я проверил изменения в IBConsole на случай, если копия Employee.Gdb окажется не той, что я предполагал.

Впоследствии я обнаружил, что могу создавать и открывать базу данных в коде с помощью Delphi Seattle и Interbase XE7 следующим образом:

function LongPath : String;
begin
  Result := 'D:\' + DupeString('abcdefghij0123456789', 8);
end;

function LongDBName : String;
begin
  Result := LongPath + '\Employee.Gdb';
end;

procedure TForm1.OpenDB;
var
  Ini : TMemIniFile;
const
  scDBXConIni = 'C:\Users\Public\Documents\Embarcadero\Studio\dbExpress\17.0\dbxconnections.ini';
  scSourceDB = 'D:\Delphi\Databases\Interbase\Employee.Gdb';
begin
  Ini := TMemIniFile.Create(scDBXConIni);
  try
    // First, blank out the Database value in the IBConnection section
    //  of DBXConnections.Ini
    Ini.WriteString('IBConnection', 'Database', '');
    Ini.UpdateFile;

    //  Next, create the long-named directory and copy Employee.Gdb to it
    if not DirectoryExists(LongPath) then
      MkDir(LongPath);
     Assert(CopyFile(PChar(scSourceDB), PChar(LongDBName), False));

     //  Set LoadParamsOnConnect to False so that the SqlConnection uses
     //  the value of the Database we are about to give it
     SqlConnection1.LoadParamsOnConnect := False;
     SqlConnection1.Params.Values['Database'] := LongDBName;
     SqlConnection1.Connected := True;

     //  Open the CDS to view the data
     CDS1.Open;

  finally
    Ini.Free;
  end;

end;

Важным шагом в этом способе является установка LoadParamsOnConnect на False, что, признаюсь, я упустил из виду в предыдущих попытках заставить этот код работать.

У меня есть более ранние версии Delphi на этом компьютере, поэтому, если вы не используете Сиэтл и приведенный выше код не работает, сообщите мне, какую из них вы используете, и я посмотрим, смогу ли я попробовать это.

**[Исходный ответ]

На самом деле, я думаю, что это может быть ошибка, возникающая в одной из DLL DBX.

Я создал папку со 160-символьным именем, затем скопировал в нее демонстрационную базу данных Employee.Gdb. IBConsole Interbase XE7 может открыть базу данных без ошибок. То же самое можно сказать и о небольшом тестовом проекте с использованием компонентов IBX в Delphi Seattle.

Однако с эквивалентным проектом DBX, когда я использую приведенный ниже код

procedure TForm1.Button1Click(Sender: TObject);
begin
  SqlConnection1.Params.Values['database'] := 'D:\abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890\employee.gdb';
  SqlConnection1.Connected := True;
end;

я получаю ошибку в

procedure TDBXDynalinkConnection.DerivedOpen;
var
  Count:          TInt32;
  Names:          TWideStringArray;
  Values:         TWideStringArray;
  IsolationLevel: Longint;
  DBXError:       TDBXErrorCode;
begin
  Count := FConnectionProperties.Properties.Count;
  FConnectionProperties.GetLists(Names, Values);

  CheckResult(FMethodTable.FDBXConnection_Connect(FConnectionHandle, Count, Names, Values));
  DBXError := FMethodTable.FDBXConnection_GetIsolation(FConnectionHandle, IsolationLevel);

"Ошибка ввода-вывода для файла "database.gdb" Ошибка при попытке открыть файл Операция успешно завершена"

и параметр базы данных SqlConnection остается со значением «Database.Gdb», что не значение, которое я указал, конечно, и не значение, указанное в параметрах в IDE, что был 'd:\delphi\databases\interbase\employee.gdb'.

Я задавался вопросом, могу ли я обойти эту проблему, SUBSTing диск на путь «abcdefg…». Я попробовал это и открыл базу данных как "x:\employee.gdb" , но я получаю ту же ошибку в своем приложении DBX, а также IBConsole не может получить доступ к базе данных.

Я думаю, вам нужен более короткий физический путь!**

person MartynA    schedule 19.02.2016
comment
Спасибо за Ваш ответ. Хотя кажется, что вы столкнулись с немного другой проблемой, чем я. В настоящее время мой путь не превышает 160 символов. Тем не менее, я очень ценю ваши усилия :) - person RFerwerda; 22.02.2016

Это связано с сервером MSSql:

Как правило, длинные имена путей, превышающие 160 символов, могут вызвать проблемы.

из Microsoft TechNet — https://technet.microsoft.com/en-us/library/ms165768(v=sql.105).aspx

person RBA    schedule 19.02.2016