目次
- 概要
- SQLServerの単純な選択クエリが機能しない
- SOQLドライバーを使用したデータの一括挿入
- クエリバルキングの更新と削除
- Easysoftトランザクションサポート
- レイジースキーマ検証
- MicrosoftのOLEDBforODBCプロバイダーの制限
このドキュメントでは、SalesforceでSQLServerを使用するためのヒントをいくつか紹介します。 SQL ServerをSalesforceに接続するために使用されるコンポーネントは、SQLServerリンクサーバーとEasysoftSalesforceODBCドライバーです。この記事では、SQLServerをSalesforceに接続する方法について説明します。このドキュメントの例では、使用されているリンクサーバー名(SQLコマンドで参照)はSFSOQL8です。
このドキュメントのすべてのSQLは、SQLServer2017およびEasysoftSalesforceODBCドライバーバージョン2.0.0に対してテストされています。
このドキュメントに貢献したい場合は、提出物をに電子メールで送信してください。
SQLServerの単純な選択クエリが機能しない
SQLServerでこのクエリを実行しようとしているとしましょう:
SELECT Id FROM SFSOQL8...Account
SQLServerはそのSQLを次のように変換します。
SELECT "Tbl1002"."Id" "Col1004" FROM "Account" "Tbl1002"
Salesforce SOQL言語は、このような方法でのテーブルと列の名前変更をサポートしていないため、次のエラーが発生します。
OLE DB provider "MSDASQL" for linked server "SFSOQL8" returned message "[Easysoft][Salesforce SOQL ODBC Driver]General error: Query Failed: 'MALFORMED_QUERY: only aggregate expressions use field aliasing'".
Msg 7320, Level 16, State 2, Line 1
Cannot execute the query "SELECT "Tbl1002"."Id" "Col1004" FROM "Account" "Tbl1002"" against OLE DB provider "MSDASQL" for linked server "SFSOQL8".
SQL Serverには、SOQLをEasysoftドライバーに送信するために使用できる2つの方法があります。
-
OPENQUERY
、ローカルテーブルと組み合わせて使用して、リモートデータとローカルデータを結合できます。 -
EXEC
これをパラメータと一緒に使用して、Salesforceに対してSOQLを直接実行できます。
これらの方法を示すために、SOQLテーブル結合から始めます。
SELECT Id, Amount, Name, ( SELECT Quantity, ListPrice, PricebookEntry.UnitPrice, PricebookEntry.Name FROM OpportunityLineItems ) FROM Opportunity
SQL Serverでは、次のクエリのいずれかを実行できます。
SELECT * FROM OPENQUERY(SFSOQL8, 'SELECT Id, Amount, Name, ( SELECT Quantity, ListPrice, PricebookEntry.UnitPrice, PricebookEntry.Name FROM OpportunityLineItems ) FROM Opportunity')
—または—
EXEC ('SELECT Id, Amount, Name, ( SELECT Quantity, ListPrice, PricebookEntry.UnitPrice, PricebookEntry.Name FROM OpportunityLineItems ) FROM Opportunity') at SFSOQL8
作成したSOQLはSalesforceサーバーに直接渡されるため、パフォーマンスにほとんど違いはありません。
同様に、すべてのSOQL関数も同じ方法を使用して使用できます。
SELECT * FROM OPENQUERY(SFSOQL8, 'select Id, Name, DISTANCE(CustLocation__c , GEOLOCATION(37.775,-122.418), ''mi'') from Account where Name like ''Bur%'' ')>
SELECT * FROM OPENQUERY(SFSOQL8, 'SELECT Type, BillingCountry, GROUPING(Type) grpType, GROUPING(BillingCountry) grpCty, COUNT(id) accts FROM Account GROUP BY CUBE(Type, BillingCountry) ORDER BY GROUPING(Type), GROUPING(BillingCountry)')
無効なSOQLを渡した場合、EasysoftSOQLドライバーはSalesforceから直接エラーを返します。例:
SELECT * FROM OPENQUERY(SFSOQL8, 'select Id, Name, DISTANCE(CustLocation__c , GEOLOCATION(37.775,-122.418), ''mo'') from Account where Name like ''Bur%'' ')>
OLE DB provider "MSDASQL" for linked server "SFSOQL8" returned message "[Easysoft][Salesforce SOQL ODBC Driver]General error: Query Failed: 'INVALID_FIELD: select Id, Name, DISTANCE(CustLocation__c , GEOLOCATION(37.775 ^ ERROR at Row:1:Column:27 Invalid distance unit: mo. Valid unit: 'mi', 'km''". Msg 7320, Level 16, State 2, Line 1 Cannot execute the query "select Id, Name, DISTANCE(CustLocation__c , GEOLOCATION(37.775,-122.418), 'mo') from Account where Name like 'Bur%' " against OLE DB provider "MSDASQL" for linked server "SFSOQL8".
SOQL言語の詳細については、こちらをご覧ください。
SOQLドライバーを使用したデータの一括挿入
Salesforce SOAP API内には、1回のSOAPAPI呼び出しから最大200行のデータを挿入できる関数があります。 Easysoft Salesforce SOQL ODBCドライバーはこの関数を利用し、SQLServerTSQLを使用して一度に最大200行を一括ロードできます。
私の例では、Salesforce内のAccountオブジェクトに新しいレコードを追加します。これは、データの列が数列しかない非常に基本的な例ですが、これがSQLServerからの一括挿入がどのように可能であるかを説明していることを願っています。 SQL Serverには、次のようなAccountというローカルテーブルがあります。
begin declare @BlockCount as int declare @IsPosted as int declare @PrmName As nvarchar(255) declare @PrmAddress As nvarchar(255) declare @PrmTown As nvarchar(40) declare @PrmPostCode As nvarchar(30) declare @PrmDescription As nvarchar(255) declare @SQL as nvarchar(255) set @BlockCount=0 set @SQL='insert into Account (Name, BillingStreet, BillingCity, BillingPostalCode, Description ) values ( ?, ?, ?, ?, ? )' declare select_cursor cursor local FORWARD_ONLY for select AccName, "Property Description", "Address", Town, PostCode from Account Order by Id open select_cursor fetch next from select_cursor into @PrmName, @PrmAddress, @PrmTown, @PrmPostCode, @PrmDescription while @@FETCH_STATUS=0 begin if (@BlockCount=0) Begin set @IsPosted=0 exec('Begin Trans') at SFSOQL8 end set @BlockCount=@BlockCount+1 exec (@SQL, @PrmName, @PrmAddress, @PrmTown, @PrmPostCode, @PrmDescription) at SFSOQL8 if (@BlockCount=200) Begin set @IsPosted=1 exec('Commit') at SFSOQL8 end fetch next from select_cursor into @PrmName, @PrmAddress, @PrmTown, @PrmPostCode, @PrmDescription end if (@IsPosted=0) begin exec('Commit') at SFSOQL8 end close select_cursor; deallocate select_cursor; endの割り当てを解除します
このTSQLは、ローカルのアカウントテーブルをカーソルに読み込むことで機能します。
200行の最初のブロックの開始時に、Begin Trans
が呼び出されます。これは、Easysoftドライバーに、渡されたデータがCommit
のいずれかになるまで保持されることを通知します。 またはRollback
と呼ばれます。
EXEC
関数は、カーソルで見つかった各行をEasysoftドライバーに送信します。次に、ドライバーは必要なSOAPAPI呼び出しを作成します。 Easysoftに200行が送信されたら、Commit
を送信します 、これにより、ドライバーはSOAPAPI呼び出しをSalesforceに送信します。
カーソルの終わりに達したときに、Salesforceに渡されていないEasysoftドライバーに送信されたレコードがある場合は、最後のCommit
を送信します。 。その後、カーソルが閉じられ、割り当てが解除されます。
200行の制限は、Salesforceの内部制限です。 200行を超えて送信しようとすると、Salesforceエラーが発生します。 Easysoftドライバーには制限が組み込まれていないため、SalesforceがSOAP APIの将来のバージョンで200行の制限を増やすと、Easysoftドライバーは新しい制限で自動的に機能します。
この一括挿入方法を使用する場合、1つのブロックにデータを挿入できるテーブルの数に制限はないため、次のTSQLが機能します。
Begin exec('Begin Trans') at SFSOQL8 exec('Insert into Account ( Name ) values (''Richard Test'') ') at SFSOQL8 exec('Insert into Opportunity ( Name, StageName, CloseDate ) values (''Richard Test'', ''My Stage'', ''2018-08-14T10:07:00Z'') ') at SFSOQL8 exec('Commit') at SFSOQL8 End
挿入にBeginTrans/ Commitメソッドを使用する場合、送信できるのは挿入ステートメントのみです。挿入と更新はSalesforceSOAPAPIでサポートされていないため、組み合わせて使用することはできません。
SOQLドライバーには、UPDATEまたはDELETEクエリで使用する場合に、データトランザクションをバルク化するための組み込みメソッドがあります。
この例は、カスタム列を設定値に更新する方法を示しています。
EXEC ('UPDATE Account SET CustomerPriority__c=''low'' WHERE CustomerPriority__c=NULL') at SFSOQL8
SalesforceはSOQLを使用したUPDATEまたはDELETEをサポートしていないため、EasysoftドライバーはクエリをSOQLSELECTに変換する必要があります。 SELECTから返された行は、最大200のブロックにまとめられ、UPDATEまたはDELETEのために一度に1つのブロックに送信されます。
Easysoft Salesforce SOQL ODBCドライバーは、単一レベルのトランザクションのみをサポートします。つまり、Begin Trans
その後にいくつかのINSERTをCOMMIT
でSalesforceに送信できます または、ROLLBACK
を使用してドライバー内に破棄されます 。
SQL Serverの[サーバーオプション]セクションにあるリンクサーバーのプロパティには、[遅延スキーマ検証]のオプションがあります。デフォルトでは、これはFALSEに設定されており、SELECTステートメントを実行しているときにSQLServerがステートメントを2回送信します。初めて送信されるとき、SQL Serverは、返された詳細を使用して、結果セットに関するメタデータを構築します。その後、クエリが再度送信されます。これは非常にコストのかかるオーバーヘッドであるため、Easysoftは「LazySchema Validation」をTRUEに設定することをお勧めします。これは、メタデータとデータの両方を取得するSELECTが1つだけ送信されることを意味します。これにより、SalesforceAPI呼び出しの数も減ります。
OLEDB for ODBCプロバイダーの制限の詳細については、次を参照してください:
https://msdn.microsoft.com/en-us/library/ms719628(v=vs.85).aspx