Microsoft SQL Server に関する質問(FireDAC)

提供: RAD Studio
移動先: 案内検索

FAQ(FireDAC) への移動

このトピックでは、MS SQL Server に関係する質問と回答の一覧を扱います。


Q1: SQL Server 2005: SQL Native Client で共有メモリ トランスポートを使用することはできますか。

A: 一般に次のようにします。

  • クライアント ネットワーク ユーティリティを使って、共有メモリ プロトコルが有効になっていることを確認します。
  • 接続定義に Server=(local) を指定します。

Q2: SQL Server 2005 で OriginTabName を取得するにはどうすればよいでしょうか。

A: 接続定義パラメータ ExtendedMetadata=True を追加します。

Q3: ストアド プロシージャを呼び出すと、"[FireDAC][Phys][ODBC]-345. Data too large for variable [#3]. Max len = [2], actual len = [14]"([FireDAC][Phys][ODBC]-345. 変数 [#3] のデータが大きすぎます。最大長は [2] ですが実際の長さは [14] です)というメッセージが出力されます。 どこが間違っているのでしょうか。どこが間違っているのでしょうか。

A: このメッセージが出力されるのは、たいてい、サイズの指定されていない VARCHAR パラメータがストアド プロシージャに定義されている場合です。 例:

PROCEDURE ANALYZETABLE @T_OWNER VARCHAR, @T_TABLE VARCHAR AS
DECLARE @FOOBAR INTEGER;
BEGIN
  /* DUMMY PROCEDURE JUST FOR COMPATIBILITY PURPOSE */
  SET @FOOBAR = 1;
END;

メモ:

  • fiMeta を FetchOptions.Items から削除して、FireDAC がストアド プロシージャのパラメータ定義を取得しないようにしてください。 これが必要なのは、ODBC ドライバで @T_OWNER VARCHAR が VARCHAR(1) になっているためです。
  • Prepare や初回の ExecProc を呼び出す前に、Size を含むすべてのパラメータ プロパティを指定してください。

Q4: ストアド プロシージャを呼び出すと、"[FireDAC][Phys][ODBC][Microsoft][SQL Server Native Client 10.0][SQL Server]Line 1: Incorrect syntax near '{'"([FireDAC][Phys][ODBC][Microsoft][SQL Server Native Client 10.0][SQL Server]1 行目:'{' の近くに不正な構文があります)というメッセージが出力されます。 どこが間違っているのでしょうか。

A: これは既知の問題です。 次の条件をすべて満たした場合に発生します。

  • 接続で SQL Server Native Client 2008 ODBC ドライバを使用している
  • DBMS が SQL Server 2000 である
  • ストアド プロシージャに BLOB 入力パラメータが含まれている

現時点でこれを回避するには、Microsoft SQL Server 2000 への接続に SQL Server 2000 ODBC ドライバまたは SQL Native Client 2005 を使用するしかありません。

Q5: 配列 DML コマンドを呼び出すと、"[FireDAC][Phys][ODBC][Microsoft][SQL Server Native Client 10.0]String data, length mismatch"([FireDAC][Phys][ODBC][Microsoft][SQL Server Native Client 10.0]文字列データの長さが一致しません)というメッセージが出力されます。 どこが間違っているのでしょうか。

A: これは既知の問題です。 Microsoft SQL Native Client ODBC ドライバのバグだと思われます。 この問題の適切な対処法は見つかっていません。 この問題が発生するのは、パラメータのどれかが BLOB データ型(ftBlob、ftMemo など)の場合です。 回避するには、ResourceOptions.ArrayDMLSize を 1 に設定してください。

Q6: アプリケーションで "Invalid object name '#<my temp table name>'"(オブジェクト名が無効です '#<一時テーブル名>')という例外が発生するのはなぜでしょうか。

A: FireDAC アプリケーションで Microsoft SQL Server のローカルの一時テーブルを扱っているときに、上記の例外が発生する可能性があります。 次のコードでこの問題を再現できます。

FDQuery1.ExecSQL('select * into #TmpOrd from [Orders]');
FDQuery1.Open('select * from #TmpOrd');

この問題を解決するには、TFDQuery.ResourceOptions.DirectExecute を True に設定します。 この設定は、アプリケーションが頻繁に以下を使用している場合にも必要です。

  • ローカル一時テーブル(クライアント SQL 内で)
  • 動的クライアント SQL

選択肢の 1 つとして、グローバル一時テーブルを使用することを検討してください。

Q7: 不思議な SQL エラー(8155) "No column was specified for column 1 of 'A'"('A' の列 1 に列が指定されていません)が発生しています。 どこが間違っているのでしょうか。

A: アプリケーションで FetchOptions.RecsMax を 0 より大きい値に設定して、SELECT リストに式を含むクエリを実行しているものと思われます。 例:

SELECT MIN(MyField) FROM MyTable WHERE MyIdField > 0

この場合、FireDAC はクエリを次のように変更します。

SELECT TOP 10 * FROM (
  SELECT MIN(MyField) FROM MyTable WHERE MyIdField > 0
) A

SQL Server では、この構文で上記のエラーが発生します。 この問題を解決するには、SELECT リスト内の式にエイリアスを指定してください。

Q8: データベースから中国語文字(Big5 エンコーディング)を取得できません。 どうすれば修正できるでしょうか。

A: 次の接続定義パラメータを追加してみてください。

ODBCAdvanced=AutoTranslate=no

さらに、次のようにマッピング ルールを追加します。

  object FDConnection1: TFDConnection
.....................
    FormatOptions.AssignedValues = [fvMapRules]
    FormatOptions.OwnMapRules = True
    FormatOptions.MapRules = <
      item
        SourceDataType = dtAnsiString
        TargetDataType = dtWideString
      end>
  end

また、データベース文字セットが Latin1 ではなく中国語に正しく設定されていることを確認してください。

Q9: 日時値として '2011-11-13 00:00' を挿入すると、"The conversion of a varchar data type to a datetime data type resulted in an out-of-range value"(varchar データ型から datetime データ型へ変換した結果、値が範囲外になりました)というエラーが発生します。 どこが間違っているのでしょうか。

A: MSDN によると、使用した日時の形式が国際標準に準拠していません。 このエラーを回避する方法はいくつかあります。

  • SET DATEFORMAT オプションを使用します。たとえば、次の文を実行して年、月、日の順序を設定します。
FDConnection1.ExecSQL('set dateformat ymd');
  • CONVERT 関数を使用します。
FDConnection1.ExecSQL('insert into Test (date_val) values (convert(datetime, ''2011-11-13 00:00'', 120)');
  • データの形式を国際標準に変更します。
FDConnection1.ExecSQL('insert into Test (date_val) values(''2011-11-13T00:00:00'');

Q10: 更新を SQL Server のテーブルにポストすると、"Update command updated [N] instead of [1] record"(更新コマンドで [1] 件ではなく [N] 件のレコードを更新しました)というエラーが発生します。 どのような理由でしょうか。

A: SQL Server でこのエラーが発生するのは、たいてい、テーブルにトリガが設定されていて、そのトリガでデータベースを変更するストアド プロシージャを呼び出して明示的または暗黙的にデータベースを変更している場合です。 このとき、FireDAC は、UPDATE コマンドで更新されたレコードの数ではなく、トリガで変更されたレコードの数を受け取ります。

これを回避するには、トリガの先頭に SET NOCOUNT ON を挿入します。 あるいは、UpdateOptions.CountUpdatedRecords を False に設定します。

Q11: あるテーブルの列を DATETIME2/DATE/TIME と宣言しましたが、FireDAC からは WideString として返されます。 あるいは、型が一致しません、Date が必要ですが実際には WideString でした、というメッセージが出力されます。 どこが間違っているのでしょうか。

DATETIME2/DATE/TIME は SQL Server 2008 で導入されました。 SQL Server(SQL Server 2000)ODBC ドライバでは、これらの型を認識せず、WideString にマッピングします。 これらの型は、SQL Server Native Client v10 では正しく認識され、表現されます。 この問題を解決するには、SQL Server Native Client v10 をインストールする必要があります。 これはデフォルトではインストールされませんが、SQL Server ODBC ドライバはデフォルトでインストールされます。