Microsoft SQL Server に関する質問(FireDAC)
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 ドライバはデフォルトでインストールされます。