トレーニング
Odbc.DataSource のパラメータ
Odbc.DataSource 関数は 2 つのパラメーターを取ります。ドライバーの connectionString
と、ドライバーのさまざまな動作をオーバーライドできる options
レコードです。 オプション レコードを使用すると、ドライバーによって報告される機能や他の情報をオーバーライドし、ナビゲーターの動作を制御し、M エンジンによって生成される SQL クエリに影響を与えることができます。
サポートされているオプション レコード フィールドは、パブリックで常に使用できるものと、拡張性コンテキストでのみ使用できるものの 2 つのカテゴリに分類されます。
次の表では、オプション レコードのパブリック フィールドについて説明します。
フィールド | 説明 |
---|---|
CommandTimeout |
サーバー側クエリがキャンセルされるまでの実行を許可される時間を制御する期間値。 既定値: 10 分 |
ConnectionTimeout |
サーバーへの接続試行を破棄するまで待機する期間の長さを制御する値。 既定値: 15 秒 |
CreateNavigationProperties |
戻されたテーブルでナビゲーション プロパティを生成するかどうかを設定する論理値。 ナビゲーション プロパティは、ドライバーによって報告された外部キー関係に基づいています。 これらのプロパティは、クエリ エディターで展開できる「仮想」列として表示され、適切な結合を作成します。 外部キーの依存関係の計算がドライバーにとって負荷の大きい操作である場合は、この値を false に設定できます。 既定値: true |
HierarchicalNavigation |
テーブルをそのスキーマ名でグループ化して表示するかどうかを設定する論理値。 false に設定すると、テーブルは各データベースの下のフラット リストに表示されます。 既定: false |
SqlCompatibleWindowsAuth |
Windows 認証の使用時に SQL Server と互換性のある接続文字列を生成するかどうかを決定する論理値 - Trusted_Connection=Yes 。ドライバーが Windows 認証をサポートしているが、接続文字列に追加または代替の設定が必要な場合は、この値を false に設定し、次の表で説明されている CredentialConnectionString オプション レコード フィールドを使用する必要があります。既定値: true |
次の表では、拡張機能によってのみ使用できるオプション レコード フィールドについて説明します。 単純なリテラル値ではないフィールドについては、後のセクションで説明します。
フィールド | 説明 |
---|---|
AstVisitor |
SQL クエリの生成を制御する 1 つ以上のオーバーライドを含むレコード。 このフィールドの最も一般的な使用方法は、TOP をサポートしないドライバーに LIMIT/OFFSET 句を生成するロジックを提供することです。 フィールドには Constant と LimitClause が含まれます。詳細: AstVisitor のオーバーライド |
CancelQueryExplicitly |
ODBC サーバーへの接続を終了する前に、ODBC ドライバー経由で実行中のすべての呼び出しを明示的に取り消すよう M エンジンに指示する論理値。 このフィールドは、一部の Spark のデプロイなど、サーバーへのネットワーク接続とは別にクエリの実行が管理される場合に便利です。 ほとんどの場合、サーバーへのネットワーク接続が終了されるとサーバー内のクエリは取り消されるので、この値を設定する必要はあります。 既定: false |
ClientConnectionPooling |
ODBC ドライバー用にクライアント側接続プールを有効にする論理値。 ほとんどのドライバーでは、この値を true に設定する必要があります。 既定: false |
CredentialConnectionString |
資格情報関連の接続文字列プロパティを指定するために使用されるテキストまたはレコード値。 |
HideNativeQuery |
コネクタが生成された SQL ステートメントを Power Query ユーザー エクスペリエンスに表示するかどうかを制御する論理値。 バックエンド データ ソースが SQL-92 をネイティブにサポートしている場合にのみ、これを true に設定する必要があります。 既定: false |
ImplicitTypeConversions |
ドライバーまたはバックエンド サーバーでサポートされる暗黙的な型変換を含むテーブル値。 このテーブルの値は、ドライバー自体によって報告される変換に追加されます。 このフィールドは通常、ドライバーによって報告されたデータ型情報をオーバーライドするときに SQLGetTypeInfo フィールドとともに使用されます。 |
OnError |
タイプ record の errorRecord パラメーターを受け取るエラー処理関数。この関数の一般的な使用方法には、SSL 接続エラーの処理、システムでドライバーが見つからない場合のダウンロード リンクの提供、認証エラーの報告が含まれます。 |
SoftNumbers |
2 つの特定の数値型の間の変換が SQL_CONVERT_* 機能でサポートされていない場合に、M エンジンで互換性のあるデータ型を選べるようにします。 既定: false |
SqlCapabilities |
ドライバー機能のさまざまなオーバーライドと、ODBC 3.8 で表されていない機能を指定する方法を提供するレコード。 詳細: SqlCapabilities のオーバーライド |
SQLColumns |
SQLColumns 関数によって返された列メタデータを変更できる関数。詳細: SQLColumns のオーバーライド |
SQLGetFunctions |
SQLGetFunctions への呼び出しによって返される値をオーバーライドできるレコード。このフィールドは、通常、パラメーター バインドの使用を無効にする場合、または生成されるクエリで CONVERT ではなく CAST を使用する必要があることを指定する場合に使用します。 詳細: SQLGetFunctions のオーバーライド |
SQLGetInfo |
SQLGetInfo への呼び出しによって返される値をオーバーライドできるレコード。詳細: SQLGetInfo のオーバーライド |
SQLGetTypeInfo |
SQLGetTypeInfo によって返される型情報をオーバーライドするテーブルを返すテーブルまたは関数。値にテーブルを設定すると、ドライバーによって報告される型情報がその値に完全に置き換えられます。 SQLGetTypeInfo は呼び出されません。値が関数に設定されている場合、関数は SQLGetTypeInfo への元の呼び出しの結果を受け取り、テーブルを変更できるようになります。このフィールドは通常、 SQLGetTypeInfo とSQLColumns によって報告されたデータ型の間に不一致がある場合に使用されます。詳細: SQLGetTypeInfo のオーバーライド |
SQLTables |
SQLTables .の呼び出しによって返されるテーブル メタデータを変更できる関数。 |
TolerateConcatOverflow |
使用可能な型の範囲に収まるように結果が切り捨てられている場合でも、テキスト値を連結できます。 たとえば、最大 VARCHAR サイズ 4000 をサポートし CLOB 型をサポートしないシステムで VARCHAR(4000) フィールドを VARCHAR(4000) フィールドと連結すると、結果が切り捨てられる可能性があっても連結は折りたたまれます。 既定: false |
UseEmbeddedDriver |
(内部使用): (ODBC 4.0 仕様で定義されている新しい機能を使用して) ODBC ドライバーをローカル ディレクトリから読み込むかどうかを制御する論理値。 この値は通常、Power Query に付属する Microsoft によって作成されたコネクタによってのみ設定されます。 false に設定すると、システム ODBC ドライバー マネージャーを使用してドライバーを見つけてロードします。 ほとんどのコネクタでは、このフィールドを設定する必要はありません。 既定: false |
AstVisitor
フィールドは、Odbc.DataSource オプション レコードを通じて設定されます。 特定のクエリ シナリオ用に生成される SQL ステートメントを変更するために使用します。
注意
(TOP ではなく) LIMIT 句と OFFSET 句をサポートするドライバは、AstVisitor
の LimitClause
オーバーライドを提供する必要があります。
この値のオーバーライドの指定は非推奨になっており、今後の実装から削除される可能性があります。
このフィールドは、2 つの Int64.Type
引数 (skip
、take
) を受け取り、2 つのテキスト フィールド (Text
、Location
) を含むレコードを返す関数です。
LimitClause = (skip as nullable number, take as number) as record => ...
skip
パラメータは、スキップする行数 (つまり、OFFSET の引数) です。 オフセットが指定されていない場合、スキップ値は null になります。 ドライバーが LIMIT をサポートしているが OFFSET をサポートしていない場合、skip が 0 より大きい場合、 LimitClause
関数は未実装エラー (...) を返す必要があります。
take
パラメータは取得する行数 (つまり、LIMIT の引数) です。
結果の Text
フィールドには、生成されたクエリに追加する SQL テキストが格納されます。
Location
フィールドは、句を挿入する場所を指定します。 次の表では、サポートされる値を説明します。
Value | 説明 | 例 |
---|---|---|
AfterQuerySpecification |
LIMIT 句は、生成された SQL の末尾に配置されます。 これは、最も一般的にサポートされる LIMIT 構文です。 |
SELECT a, b, c FROM table WHERE a > 10 LIMIT 5 |
BeforeQuerySpecification |
LIMIT 句は、生成された SQL ステートメントの前に配置されます。 | LIMIT 5 ROWS SELECT a, b, c FROM table WHERE a > 10 |
AfterSelect |
LIMIT は SELECT ステートメントの後、およびすべての修飾子 (DISTINCT など) の後に配置されます。 | SELECT DISTINCT LIMIT 5 a, b, c FROM table WHERE a > 10 |
AfterSelectBeforeModifiers |
LIMIT は SELECT ステートメントの後で、すべての修飾子 (DISTINCT など) の前に配置されます。 | SELECT LIMIT 5 DISTINCT a, b, c FROM table WHERE a > 10 |
次のコード スニペットは、LIMIT 句と省略可能な OFFSET を次の形式で受け取るドライバー用の LimitClause の実装です: [OFFSET <offset> ROWS] LIMIT <row_count>
LimitClause = (skip, take) =>
let
offset = if (skip > 0) then Text.Format("OFFSET #{0} ROWS", {skip}) else "",
limit = if (take <> null) then Text.Format("LIMIT #{0}", {take}) else ""
in
[
Text = Text.Format("#{0} #{1}", {offset, limit}),
Location = "AfterQuerySpecification"
]
次のコード スニペットは、LIMIT をサポートするが、OFFSET はサポートしないドライバーの LimitClause
実装を提供します。 形式: LIMIT <row_count>
。
LimitClause = (skip, take) =>
if (skip > 0) then error "Skip/Offset not supported"
else
[
Text = Text.Format("LIMIT #{0}", {take}),
Location = "AfterQuerySpecification"
]
フィールド | 詳細 |
---|---|
FractionalSecondsScale |
ミリ秒値でサポートされる小数点以下の桁数を示す 1 から 7 の範囲の数値。 datetime 値に対するクエリ フォールディングを有効にするコネクタでは、この値を設定する必要があります。 既定値: null |
PrepareStatements |
SQLPrepare を使用してステートメントを準備する必要があることを示す論理値。 既定: false |
SupportsTop |
返される行数を制限するための TOP 句をドライバーがサポートすることを示す論理値。 既定: false |
StringLiteralEscapeCharacters |
文字列リテラルと LIKE 式をエスケープするときに使用する文字を指定するテキスト値のリスト。 例: {""} 既定値: null |
SupportsDerivedTable |
ドライバーが派生テーブル (サブ選択) をサポートすることを示す論理値。 この値は、適合レベルを SQL_SC_SQL92_FULL に設定するドライバーに対して true であるとみなされます (ドライバーによって報告されるか、Sql92Conformance 設定 でオーバーライドされます)。 他のすべての準拠レベルの場合、この値は既定で false に設定されます。 ドライバーが SQL_SC_SQL92_FULL 準拠レベルを報告しないが、サポート派生テーブルは報告する場合は、この値を true に設定します。 派生テーブルのサポートは、多くの DirectQuery シナリオで必要です。 |
SupportsNumericLiterals |
生成される SQL に数値リテラル値を含める必要があるかどうかを示す論理値。 false に設定すると、数値は常にパラメーター バインディングを使用して指定されます。 既定: false |
SupportsStringLiterals |
生成される SQL に文字列リテラル値を含める必要があるかどうかを示す論理値。 false に設定すると、ストリング値は常にパラメーター バインディングを使用して指定されます。 既定: false |
SupportsOdbcDateLiterals |
生成される SQL に日付リテラル値を含める必要があるかどうかを示す論理値。 false に設定すると、日付値は常にパラメーター バインディングを使用して指定されます。 既定: false |
SupportsOdbcTimeLiterals |
生成される SQL に時刻リテラル値を含める必要があるかどうかを示す論理値。 false に設定すると、時刻値は常にパラメーター バインディングを使用して指定されます。 既定: false |
SupportsOdbcTimestampLiterals |
生成される SQL にタイムスタンプ リテラル値を含める必要があるかどうかを示す論理値。 false に設定すると、タイムスタンプ値は常にパラメーター バインディングを使用して指定されます。 既定: false |
SQLColumns
は、SQLColumns に対する ODBC 呼び出しの結果を受け取る関数ハンドラーです。 ソース パラメーターには、データ型の情報に関するテーブルが含まれています。 このオーバーライドは、通常、SQLGetTypeInfo
と SQLColumns
の呼び出しの間でデータ型の不一致を修正するために使用されます。
ソース テーブル パラメーターの形式について詳しくは、「SQLColumns 関数」をご覧ください。
このフィールドは、ODBC ドライバーによって返される SQLFunctions
値をオーバーライドするために使用されます。 これには、フィールド名が ODBC SQLGetFunctions関数に定義された FunctionId
定数と等しいレコードが含まれています。 これらの各フィールドの数値定数は、ODBC の仕様で確認できます。
フィールド | 詳細 |
---|---|
SQL_CONVERT_FUNCTIONS |
型変換を実行するときにサポートされる関数を示します。 デフォルトでは、M エンジンは CONVERT 関数の使用を試みます。 CAST の使用を優先するドライバーでは、この値をオーバーライドして、SQL_FN_CVT_CAST (0x2 の数値) のみがサポートされていることを報告できます。 |
SQL_API_SQLBINDCOL |
データを取得するときにマッシュアップ エンジンが SQLBindCol API を使用する必要があるかどうかを示す論理 (true/false) 値。 false に設定すると、代わりに SQLGetData が使用されます。 既定: false |
次のコード スニペットは、CONVERT ではなく CAST を使用するように M エンジンに明示的に指示する例です。
SQLGetFunctions = [
SQL_CONVERT_FUNCTIONS = 0x2 /* SQL_FN_CVT_CAST */
]
このフィールドは、ODBC ドライバーによって返される SQLGetInfo
値をオーバーライドするために使用されます。 これには、ODBC SQLGetInfo 関数に定義された InfoType
定数と同じ名前のフィールドを持つレコードが含まれています。 これらの各フィールドの数値定数は、ODBC の仕様で確認できます。 チェックされる InfoTypes
の完全なリストは、マッシュアップ エンジンのトレース ファイルにあります。
次の表には、一般的にオーバーライドされる SQLGetInfo
プロパティが含まれています。
フィールド | 詳細 |
---|---|
SQL_SQL_CONFORMANCE |
ドライバーによってサポートされる SQL-92 のレベルを示す整数値: (1) SQL_SC_SQL92_ENTRY: エントリーレベルの SQL-92 準拠。 (2) SQL_SC_FIPS127_2_TRANSITIONAL: FIPS 127-2 移行レベルに準拠。 (4) SQL_SC_ SQL92_INTERMEDIATE" 中級レベルの SQL-92 準拠。 (8) SQL_SC_SQL92_FULL: フルレベル SQL-92 準拠。 Power Query シナリオでは、コネクタは読み取り専用モードで使用されます。 ほとんどのドライバーは、SQL_SC_SQL92_FULL 準拠レベルを報告し、 SQLGetInfo プロパティとSQLGetFunctions プロパティを使用して特定の SQL 生成動作をオーバーライドします。 |
SQL_SQL92_PREDICATES |
SQL-92 で定義されているように、SELECT ステートメントでサポートされる述語を列挙するビットマスク。 ODBC 仕様の「SQL_SP_* 定数」に進みます。 |
SQL_AGGREGATE_FUNCTIONS |
集計関数のサポートを列挙するビットマスク。 SQL_AF_ALL SQL_AF_AVG SQL_AF_COUNT SQL_AF_DISTINCT SQL_AF_MAX SQL_AF_MIN SQL_AF_SUM ODBC 仕様の「SQL_AF_* 定数」に進みます。 |
SQL_GROUP_BY |
GROUP BY 句の列と選択リストの非集計列の間の関係を指定する整数値。 SQL_GB_COLLATE: COLLATE 句は各グループ化列の最後に指定できます。 SQL_GB_NOT_SUPPORTED: GROUP BY 句はサポートされていません。 SQL_GB_GROUP_BY_EQUALS_SELECT: GROUP BY 句には、選択リスト内のすべての非集計列が含まれている必要があります。 他の列を含めることはできません。 例: SELECT DEPT, MAX(SALARY) FROM EMPLOYEE GROUP BY DEPT。 SQL_GB_GROUP_BY_CONTAINS_SELECT: GROUP BY 句には、選択リスト内のすべての非集計列が含まれている必要があります。 選択リストにない列を含めることができます。 例: SELECT DEPT, MAX(SALARY) FROM EMPLOYEE GROUP BY DEPT, AGE。 SQL_GB_NO_RELATION: GROUP BY 句の列と選択リストは関連していません。 選択リスト内のグループ化されていない非集計列の意味は、データ ソースによって異なります。 例: SELECT DEPT, SALARY FROM EMPLOYEE GROUP BY DEPT, AGE。 ODBC 仕様の「SQL_GB_* 定数」に進みます。 |
次のヘルパー関数を使用して、整数値のリストからビットマスク値を作成できます。
Flags = (flags as list) =>
let
Loop = List.Generate(
()=> [i = 0, Combined = 0],
each [i] < List.Count(flags),
each [i = [i]+1, Combined =*Number.BitwiseOr([Combined], flags{i})],
each [Combined]),
Result = List.Last(Loop, 0)
in
Result;
SQLGetTypeInfo
は、2 つの方法で指定できます。
table
の ODBC 呼び出しと同じ型情報を含む固定のSQLGetTypeInfo
値。- テーブル引数を受け取ってテーブルを返す関数。 引数には、
SQLGetTypeInfo
への ODBC 呼び出しの元の結果が含まれます。 関数の実装により、このテーブルを変更または追加できます。
1 番目の方法は、ODBC ドライバーによって返される値を完全にオーバーライドするために使用します。 2 番目の方法は、これらの値を追加または変更する場合に使用します。
タイプ テーブル パラメータの形式と予想される戻り値の詳細については、SQLGetTypeInfo 関数リファレンスを参照してください。
次のコード スニペットは、SQLGetTypeInfo
の静的実装を提供します。
SQLGetTypeInfo = #table(
{ "TYPE_NAME", "DATA_TYPE", "COLUMN_SIZE", "LITERAL_PREF", "LITERAL_SUFFIX", "CREATE_PARAS", "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_UNIQUE_VALUE", "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX", "INTERNAL_PRECISION", "USER_DATA_TYPE" }, {
{ "char", 1, 65535, "'", "'", "max. length", 1, 1, 3, null, 0, null, "char", null, null, -8, null, null, 0, 0 },
{ "int8", -5, 19, "'", "'", null, 1, 0, 2, 0, 10, 0, "int8", 0, 0, -5, null, 2, 0, 0 },
{ "bit", -7, 1, "'", "'", null, 1, 1, 3, null, 0, null, "bit", null, null, -7, null, null, 0, 0 },
{ "bool", -7, 1, "'", "'", null, 1, 1, 3, null, 0, null, "bit", null, null, -7, null, null, 0, 0 },
{ "date", 9, 10, "'", "'", null, 1, 0, 2, null, 0, null, "date", null, null, 9, 1, null, 0, 0 },
{ "numeric", 3, 28, null, null, null, 1, 0, 2, 0, 0, 0, "numeric", 0, 0, 2, null, 10, 0, 0 },
{ "float8", 8, 15, null, null, null, 1, 0, 2, 0, 0, 0, "float8", null, null, 6, null, 2, 0, 0 },
{ "float8", 6, 17, null, null, null, 1, 0, 2, 0, 0, 0, "float8", null, null, 6, null, 2, 0, 0 },
{ "uuid", -11, 37, null, null, null, 1, 0, 2, null, 0, null, "uuid", null, null, -11, null, null, 0, 0 },
{ "int4", 4, 10, null, null, null, 1, 0, 2, 0, 0, 0, "int4", 0, 0, 4, null, 2, 0, 0 },
{ "text", -1, 65535, "'", "'", null, 1, 1, 3, null, 0, null, "text", null, null, -10, null, null, 0, 0 },
{ "lo", -4, 255, "'", "'", null, 1, 0, 2, null, 0, null, "lo", null, null, -4, null, null, 0, 0 },
{ "numeric", 2, 28, null, null, "precision, scale", 1, 0, 2, 0, 10, 0, "numeric", 0, 6, 2, null, 10, 0, 0 },
{ "float4", 7, 9, null, null, null, 1, 0, 2, 0, 10, 0, "float4", null, null, 7, null, 2, 0, 0 },
{ "int2", 5, 19, null, null, null, 1, 0, 2, 0, 10, 0, "int2", 0, 0, 5, null, 2, 0, 0 },
{ "int2", -6, 5, null, null, null, 1, 0, 2, 0, 10, 0, "int2", 0, 0, 5, null, 2, 0, 0 },
{ "timestamp", 11, 26, "'", "'", null, 1, 0, 2, null, 0, null, "timestamp", 0, 38, 9, 3, null, 0, 0 },
{ "date", 91, 10, "'", "'", null, 1, 0, 2, null, 0, null, "date", null, null, 9, 1, null, 0, 0 },
{ "timestamp", 93, 26, "'", "'", null, 1, 0, 2, null, 0, null, "timestamp", 0, 38, 9, 3, null, 0, 0 },
{ "bytea", -3, 255, "'", "'", null, 1, 0, 2, null, 0, null, "bytea", null, null, -3, null, null, 0, 0 },
{ "varchar", 12, 65535, "'", "'", "max. length", 1, 0, 2, null, 0, null, "varchar", null, null, -9, null, null, 0, 0 },
{ "char", -8, 65535, "'", "'", "max. length", 1, 1, 3, null, 0, null, "char", null, null, -8, null, null, 0, 0 },
{ "text", -10, 65535, "'", "'", "max. length", 1, 1, 3, null, 0, null, "text", null, null, -10, null, null, 0, 0 },
{ "varchar", -9, 65535, "'", "'", "max. length", 1, 1, 3, null, 0, null, "varchar", null, null, -9, null, null, 0, 0 },
{ "bpchar", -8, 65535, "'", "'", "max. length", 1, 1, 3, null, 0, null, "bpchar", null, null, -9, null, null, 0, 0 } }
);
次のコード スニペットでは、ドライバーによって返される既存の型に bpchar
型を追加しています。
SQLGetTypeInfo = (types as table) as table =>
let
newTypes = #table(
{
"TYPE_NAME",
"DATA_TYPE",
"COLUMN_SIZE",
"LITERAL_PREF",
"LITERAL_SUFFIX",
"CREATE_PARAS",
"NULLABLE",
"CASE_SENSITIVE",
"SEARCHABLE",
"UNSIGNED_ATTRIBUTE",
"FIXED_PREC_SCALE",
"AUTO_UNIQUE_VALUE",
"LOCAL_TYPE_NAME",
"MINIMUM_SCALE",
"MAXIMUM_SCALE",
"SQL_DATA_TYPE",
"SQL_DATETIME_SUB",
"NUM_PREC_RADIX",
"INTERNAL_PRECISION",
"USER_DATA_TYPE"
},
// we add a new entry for each type we want to add
{
{
"bpchar",
-8,
65535,
"'",
"'",
"max. length",
1,
1,
3,
null,
0,
null,
"bpchar",
null,
null,
-9,
null,
null,
0,
0
}
}),
append = Table.Combine({types, newTypes})
in
append;
ODBC ドライバーの接続文字列は、Odbc.DataSource 関数と Odbc.Query 関数の最初の引数を使用して設定されます。 値には、テキストまたは M レコードを指定できます。 レコードを使用すると、レコード内の各フィールドが接続文字列のプロパティになります。 すべての接続文字列には Driver
フィールド (ユーザーがシステム レベルの DSN を事前に構成する必要がある場合は DSN
フィールド) が必要です。 資格情報関連のプロパティは個別に設定されます。 他のプロパティはドライバー固有です。
以下のコード スニペットは、新しいデータ ソース関数の定義、ConnectionString
レコードの作成、および Odbc.DataSource 関数の呼び出しを示しています。
[DataSource.Kind="SqlODBC", Publish="SqlODBC.Publish"]
shared SqlODBC.Contents = (server as text) =>
let
ConnectionString = [
Driver = "SQL Server Native Client 11.0",
Server = server,
MultiSubnetFailover = "Yes",
ApplicationIntent = "ReadOnly",
APP = "PowerBICustomConnector"
],
OdbcDatasource = Odbc.DataSource(ConnectionString)
in
OdbcDatasource;