Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Tipps zur Verwendung von SQL Server mit Salesforce

Inhaltsverzeichnis

  1. Übersicht
  2. WHERE-Klausel
  3. Mehrere Tabellenverknüpfungen
  4. Lokale Tabelle, die an eine entfernte Tabelle angehängt ist
  5. Einfügen, Aktualisieren und Löschen
  6. Aktualisieren
  7. Mit Parametern aktualisieren
  8. Einfügen eines neuen Datensatzes und Erhalten eines BLOB-Fehlers
  9. Abrufen der Salesforce-ID für den zuletzt eingefügten Datensatz
  10. Aktualisieren von SQL Server-Daten bei Änderungen von Salesforce-Daten
  11. Lazy Schema-Validierung
  12. Einschränkungen von Microsofts OLEDB für ODBC-Anbieter
  13. Wie finde ich Datensätze mit einem Zeilenumbruch (newline) in der Rechnungsadresse?
  14. Kann ich sehen, welche Tische über die Easysoft-Software verfügbar sind?
  15. Kann ich sehen, welche Spalten über die Easysoft-Software verfügbar sind?
  16. Kann ich programmgesteuert einen Verbindungsserver erstellen?

Übersicht

Dieses Dokument enthält einige Tipps zur Verwendung von SQL Server mit Salesforce. Die zum Verbinden von SQL Server mit Salesforce verwendeten Komponenten sind ein SQL Server Linked Server und der Easysoft Salesforce ODBC-Treiber. Wie Sie SQL Server mit Salesforce verbinden, wird in diesem Artikel beschrieben. Für die Beispiele in diesem Dokument lautet der Name des Verbindungsservers (auf den Sie in Ihren SQL-Befehlen verweisen) SF8.

Das gesamte SQL in diesem Dokument wurde mit SQL Server 2017 und den Easysoft Salesforce ODBC-Treiberversionen 2.0.0 bis 2.0.7 getestet.

Die SQL Server-Funktionen OPENQUERY und EXEC (EXECUTE ) wurden in SQL Server 2008 eingeführt und diese Funktionen sind mit allen Versionen von SQL Server nach 2008 kompatibel.

Wir haben dieses Dokument als Antwort auf eine Reihe von Anfragen geschrieben, die unser Support-Team bezüglich der Verbindung von SQL Server über Easysoft mit Salesforce erhalten hat. Die SQL-Beispiele sollten jedoch auch für Linked Server-Verbindungen nützlich sein, die einen anderen ODBC-Treiber und ein anderes Backend verwenden.

Wenn Sie zu diesem Dokument beitragen möchten, senden Sie Ihre Einreichung bitte per E-Mail an .

WHERE-Klausel

Ein häufig gemeldetes Problem ist „Eine einfache WHERE-Klausel braucht lange, um nur eine Zeile zurückzugeben“. Zum Beispiel:

select Id, FirstName, LastName from SF8.SF.DBO.Contact where Id='00346000002I95MAAS'

SQL Server konvertiert die obige Abfrage und sendet diese an den Salesforce-ODBC-Treiber:

select Id, FirstName, LastName from SF.DBO.Contact

Die WHERE-Klausel wird immer entfernt, wodurch der ODBC-Treiber gezwungen wird, alle Zeilen für diese Tabelle zurückzugeben. Dann filtert SQL Server sie lokal, um Ihnen die erforderliche(n) Zeile(n) zu geben. Es scheint egal zu sein, welche WHERE-Klausel Sie angegeben haben, diese wird niemals an den ODBC-Treiber weitergegeben.

Die einfache Lösung hierfür ist die Verwendung von SQL Server OPENQUERY funktionieren stattdessen. Zum Beispiel:

select * from OPENQUERY(SF8,'select Id, FirstName, LastName from SF.DBO.Contact where Id=''00346000002I95MAAS'' ')

Das gesamte SQL, das Sie innerhalb von OPENQUERY ausführen Funktion wird direkt an den Treiber übergeben, einschließlich des WHERE Klausel.

Mehrere Tabellenverknüpfungen

Hier ist ein einfacher Zwei-Tabellen-Join, bei dem beide Tabellen vom Verbindungsserver zurückkommen.

select a.[Name], BillingStreet, c.[Name] from SF8.SF.DBO.Account a, SF8.SF.DBO.Contact c where a.Id=c.AccountID and a.[Name] like 'United%'

SQL Server sendet die folgenden Abfragen an den ODBC-Treiber.

select * from Account
select * from Contact

SQL Server führt dies aus, um eine Liste mit Spaltennamen und Datentypen abzurufen. Anschließend sendet es diese Abfragen an den ODBC-Treiber.

SELECT "Tbl1001"."Id" "Col1042","Tbl1001"."Name" "Col1044","Tbl1001"."BillingStreet" "Col1046" FROM "SF"."DBO"."Account" "Tbl1001" ORDER BY "Col1042" ASC
SELECT "Tbl1003"."AccountId" "Col1057","Tbl1003"."Name" "Col1058" FROM "SF"."DBO"."Contact" "Tbl1003" ORDER BY "Col1057" ASC

Die Daten aus beiden Abfragen werden an lokale Tabellen zurückgegeben, dann wird die WHERE-Klausel in die Account-Tabelle eingefügt und die Daten aus beiden Tabellen werden verknüpft und zurückgegeben.

Wieder die Verwendung von OPENQUERY stellt sicher, dass das von Ihnen geschriebene SQL direkt an den ODBC-Treiber übergeben wird, sodass Sie stattdessen in SQL Server Folgendes ausführen würden:

select * from OPENQUERY(SF8,'select a.[Name], BillingStreet, c.[Name] from SF.DBO.Account a, SF.DBO.Contact c where a.Id=c.AccountID and a.[Name] like ''United%'' ')

Sie benötigen eine geringfügige Änderung, da SQL Server nicht mehrere Spalten mit demselben "Namen" verarbeiten kann, sodass Sie eine dieser Spalten umbenennen müssen. Zum Beispiel:

select * from OPENQUERY(SF8,'select a.[Name], BillingStreet, c.[Name] as FullName from SF.DBO.Account a, SF.DBO.Contact c where a.Id=c.AccountID and a.[Name] like ''United%'' ')

Dies zwingt den ODBC-Treiber, das gesamte SQL auf einmal zu verarbeiten und nur die erforderlichen Ergebnisse zurückzugeben.

Lokale Tabelle, die an eine entfernte Tabelle angehängt ist

In diesem Beispiel wurde die lokale Tabelle durch Ausführen von.

erstellt
select * into LocalAccount from SF8.SF.DBO.Account

Der Join der beiden Tabellen sieht nun so aus.

select a.[Name], BillingStreet, c.[Name] as FullName from LocalAccount a, SF8.SF.DBO.Contact c where a.Id=c.AccountID and a.[Name] like 'United%'

Dadurch sendet SQL Server dreimal die folgende Abfrage an den ODBC-Treiber.

select * from Contact

In mindestens einer dieser Abfragen fragt SQL Server nach allen Daten in der Tabelle. Dann fragt SQL Server nach:

SELECT "Tbl1003"."Name" "Col1008" FROM "SF"."DBO"."Contact" "Tbl1003" WHERE ?="Tbl1003"."AccountId"

SQL Server übergibt dann anstelle des "?" -Parameter, bei dem die Spalte LocalAccount.[Name] mit der LIKE-Klausel übereinstimmt.

Wenn die ODBC-Tabelle die zweite Tabelle in der Abfrage ist, können Sie schneller nur die Spalten abrufen, die Sie aus der ODBC-Tabelle benötigen. Dies kann durch die Verwendung von OPENQUERY erfolgen Funktion. Zum Beispiel:

select a.[Name], BillingStreet, c.[Name] as FullName from LocalAccount a, openquery(SF8,'select [Name], AccountId from SF.DBO.Contact') c where a.Id=c.AccountID and a.[Name] like 'United%'

Während dies immer noch alle Zeilen aus der Kontakttabelle abruft, erhält es nur die benötigten Spalten und ist daher schneller als die Standardabfrage.

Eine andere Möglichkeit wäre die Verwendung eines Cursors und einer temporären Tabelle. Zum Beispiel:

Begin
      declare @AccountId as varchar(20)
      declare @SQL as varchar(1024)

      -- Create a temporary table to store the Account information. The Id check ensures 0 rows of data are returned
      select * into #LocalContact from openquery(SF8,'select [Name], AccountId from SF.DBO.Contact where Id=''000000000000000000'' ')
      
      -- Set up the cursor      
      declare selcur cursor for
            select distinct Id from LocalAccount where [Name] like 'United%'
      
      	open selcur
      	fetch next from selcur into @AccountId
      	while @@FETCH_STATUS=0
      	Begin
      		select @SQL ='insert into #LocalContact select [Name], '''+@AccountId+''' from OPENQUERY(SF8,''select [Name] from Contact where AccountId=''''' + @AccountId + ''''' '')'
      		exec (@SQL)
      		
      		fetch next from selcur into @AccountId
      	End
      	close selcur
      	deallocate selcur
	
      	-- Next, join your tables and view the data      	
      	select a.[Name], BillingStreet, c.[Name] as FullName from LocalAccount a, #LocalContact c where a.Id=c.AccountID and a.[Name] like 'United%'
      
      	-- Don't forget to remove the temporary table
      	drop table #LocalContact
      
      End

Diese Methode kann um ein Vielfaches schneller sein als OPENQUERY Methode, die im vorherigen Beispiel gezeigt wurde, wenn die WHERE-Klausel, die an den Easysoft ODBC-Treiber übergeben wird, einen Index in Salesforce verwendet.

Einfügen, aktualisieren und löschen

Wenn Sie eine Abfrage ausführen, die keine SELECT-Abfrage ist, verwenden Sie am besten die EXEC von SQL Server Funktion. Wenn Ihr Verbindungsserver EXEC nicht verwenden kann , erhalten Sie eine Nachricht ähnlich der folgenden:

Server 'SF8' is not configured for RPC.

Um EXEC zu verwenden , klicken Sie mit der rechten Maustaste auf Ihren verknüpften Server und wählen Sie Eigenschaften. Setzen Sie im Bereich „Server Options“ „RPC Out“ auf „True“. Sie können dann die EXEC verwenden Funktion.

Aktualisieren

Angenommen, Sie haben diese Anweisung in SQL Server:

UPDATE SF8.SF.DBO.Contact SET LastName='James' WHERE Id='00346000002I95MAAS'

SQL Server sendet dieses SQL an den ODBC-Treiber.

select * from "SF"."DBO"."Contact"

Alle Datensätze werden abgerufen und SQL Server sendet diese Anweisung dann an den ODBC-Treiber.

UPDATE "SF"."DBO"."Contact" SET "LastName"=? WHERE "Id"=? AND "LastName"=?

SQL Server tut dies, um sicherzustellen, dass der Datensatz zwischen dem Ausführen der Abfrage und dem Ausführen von UPDATE nicht geändert wird. Eine schnellere Methode ist die Verwendung von SQL Server EXEC Funktion. Zum Beispiel:

exec ('update SF.DBO.Contact set LastName=''James'' where Id=''00346000002I95MAAS''' ) at SF8 

SQL Server sendet den gesamten von Ihnen eingegebenen String an den ODBC-Treiber, sodass die Abfrage ausgeführt wird, ohne die gesamte Tabelle auszuwählen.

Mit Parametern aktualisieren

Angenommen, Sie haben:

Begin
	declare @Id varchar(20)='00346000002I95MAAS'
	declare @LastName varchar(20)='James'
	update SF8.SF.DBO.Contact set LastName=@LastName where Id=@Id
End

Dies funktioniert genauso wie in den Update-Hinweisen beschrieben. Allerdings ist die Syntax bei Verwendung der EXEC Funktionsänderungen:

Begin
      	declare @Id varchar(20)='00346000002I95MAAS'
      	declare @LastName varchar(20)='James'
	exec ('update SF.DBO.Contact set LastName=? where Id=?', @LastName, @Id)
      		at SF8
End

Wo Sie eine Spalte wie LastName= haben Sie setzen ein ? anstelle von @LastName um darzustellen, was Sie in den Parameter übergeben werden. Die Parameter werden dann nach der UPDATE-Anweisung in der Reihenfolge aufgelistet, in der sie gelesen werden müssen.

Einfügen eines neuen Datensatzes und Erhalten eines BLOB-Fehlers

Angenommen, Sie versuchen Folgendes auszuführen:

insert into SF8.SF.DBO.Contact ( FirstName, LastName ) values ('Easysoft','Test')

SQL Server sendet dies an den ODBC-Treiber:

select * from "SF"."DBO"."Contact"

Dies wird zweimal durchgeführt. Bei der ersten Ausführung prüft SQL Server, ob die Ergebnismenge aktualisierbar ist. Beim zweiten Senden wechselt SQL Server zu einem leeren Datensatz nach dem letzten zurückgegebenen Datensatz und versucht, ein positionelles INSERT auszuführen, was einen Fehler ausgibt.

OLE DB provider "MSDASQL" for linked server "SF8" returned message "Query-based insertion or updating of BLOB values is not supported.".

Diese Nachricht wird zurückgegeben, weil eine positionelle Einfügung versucht, alle Spalten mit NULL-Werten einzufügen, mit Ausnahme derjenigen, die Sie in Ihrer INSERT-Anweisung angegeben haben, und im Fall der Kontakttabelle ein BLOB (Long Text Area in Salesforce) vorhanden ist. die der OLE DB Provider von Microsoft nicht unterstützt. Der Easysoft Salesforce ODBC-Treiber unterstützt das Einfügen aller Felder in Salesforce, wo Sie die Berechtigung zum Einfügen von Daten haben. Um dies zu umgehen, brauchen Sie nur EXEC.

zu verwenden
exec ('insert into SF.DBO.Contact ( FirstName, LastName ) values (''Easysoft'',''Test'')') at SF8

Dadurch wird das INSERT einfach direkt an den ODBC-Treiber gesendet.

Abrufen der Salesforce-ID für den zuletzt eingefügten Datensatz

Wir wurden von einigen unserer Kunden gefragt, was die einfachste Methode ist, um die ID der gerade eingefügten Zeile zu erhalten. Dieses Beispiel zeigt, wie Sie die ID des letzten Datensatzes erhalten, den Sie in die Tabelle "Kontakt" eingefügt haben.

Begin
	declare @Id varchar(20)='00346000002I95MAAS'
      	declare @FirstName varchar(20)='Easysoft'
      	declare @LastName varchar(20)='Test'
      	declare @FindTS varchar(22)=convert(varchar(22),GETUTCDATE(),120)
      	declare @SQL as varchar(1024)
      
      	exec ('insert into SF.DBO.Contact (FirstName, LastName ) values (?, ?)', @FirstName, @LastName ) at SF8

      	select @SQL='select Id from openquery(SF8, ''select top 1 c.Id from [User] u, Contact c where u.Username=CURRENT_USER and c.CreatedDate>={ts '''''+@FindTS+'''''} and c.CreatedById=u.Id order by c.CreatedDate desc'')'

      	exec (@SQL) 

End

Wenn ein Datensatz in Salesforce erstellt wird, enthält die Spalte „CreatedDate“ einen Zeitstempel, der die UTC (Koordinierte Weltzeit) darstellt, zu der der Datensatz erstellt wurde, und nicht unbedingt Ihr aktuelles Datum/Ihre aktuelle Uhrzeit. Die @FindTs string wird auf die UTC gesetzt, bevor INSERT stattfindet, wenn also SELECT zum Abrufen der ID aufgerufen wird, werden nur die nach @FindTS eingefügten Zeilen betrachtet eingestellt wurde.

Während des SELECT wird der Easysoft CURRENT_USER Die Funktion wird auch verwendet, um die von Salesforce zurückgegebenen Zeilen auf den Benutzer zu beschränken, der die Daten eingefügt hat.

Aktualisieren von SQL Server-Daten, wenn sich Salesforce-Daten ändern

Dieser Abschnitt zeigt Ihnen, wie Sie eine neue SQL Server-Tabelle basierend auf der Struktur einer Salesforce-Tabelle erstellen und diese Tabelle aktualisieren, wenn es Änderungen in dieser Salesforce-Tabelle gibt.

create procedure SFMakeLocal( @Link varchar(50), @Remote varchar(50), @Local varchar(50), @DropLocal int) as
          declare @SQL as nvarchar(max)
          begin
              /* Imports the data into a local table */
              /* Set DropLocal to 1 to drop the local table if it exists */
      
              if OBJECT_ID(@Local, 'U') IS NOT NULL 
              begin
                  if (@DropLocal=1) 
                  begin
                      set @SQL='DROP TABLE dbo.'+@Local
                      exec ( @SQL)
                  end
              else
                  RAISERROR(15600,1,1, 'Local table already exists')
                  RETURN  
              end
      
              set @SQL='select * into dbo.'+@Local+' from OPENQUERY('+@Link+',''select * from '+@Remote+''')'
              
              exec(@SQL)
      		select 'Local Table :'+@Local+' created.'
          end
      
      -- @Link Your SQL Server linked server
      -- @Remote The name of the table within Salesforce
      -- @Local The local table you want the data to be stored in
      -- @DropLocal Set to 1 if the table exists and you want to drop it

Führen Sie das Verfahren aus, um die Datensatzstruktur aus der Salesforce-Tabelle in die lokale Tabelle zu kopieren, und übertragen Sie dann alle Salesforce-Daten. Dieser Beispielbefehl verwendet die Account-Tabelle. Dieser Vorgang kann abhängig von der Datenmenge in der Salesforce-Tabelle eine ganze Weile dauern.

SFMakeLocal 'SF8','Account','LocalAccount', 0

Die Argumente sind:

Argument Wert
SF8 Der Name des SQL Server Linked Servers.
Konto Der Salesforce-Tabellenname, den Sie zum Lesen der Struktur und der Daten verwenden möchten.
Lokales Konto Der Name Ihrer Tabelle in SQL Server.
0 Dieser Standardwert kann auf 1 geändert werden, wenn Sie weitere benutzerdefinierte Spalten zu Salesforce hinzufügen und die lokale Tabelle löschen möchten, um sie mit den neuen Spalten erneut zu erstellen.

Der nächste Schritt besteht darin, zwei weitere Prozeduren zu erstellen, die die lokale Tabelle aktualisieren, wenn Daten aktualisiert oder in die Salesforce-Tabelle eingefügt werden:

create procedure SFUpdateTable ( @Link varchar(50), @Remote varchar(50),
      create procedure SFUpdateTable  
      @Link varchar(50), @Remote varchar(50), @LocalTable varchar(50) 
      as
          begin
              -- Updates the data into a local table based on changes in Salesforce.
      
      		declare @TempDef as varchar(50)='##EasyTMP_'
      		declare @TempName as varchar(50)
      		declare @TempNumber as decimal
      
      		declare @CTS as datetime=current_timestamp
      		declare @TTLimit int = 100
              declare @MaxCreated as datetime
              declare @MaxModified as datetime
              declare @SQL as nvarchar(max)
      		declare @RC as int
      
      		-- The first step is to create a global temporary table.
      
      		set @TempNumber=datepart(yyyy,@CTS)*10000000000+datepart(mm,@CTS)*100000000+datepart(dd,@CTS)*1000000+datepart(hh,@CTS)*10000+datepart(mi,@CTS)*100+datepart(ss,@CTS)
      		set @TempName=@TempDef+cast(@TempNumber as varchar(14))
      
      		while OBJECT_ID(@TempName, 'U') IS NOT NULL 
              begin
                  RAISERROR (15600,1,1, 'Temp name already in use.')
                  RETURN  
              end
      
      		set @SQL='select * into '+@TempName+' from '+@LocalTable+' where 1=0'
      
      		create table #LocalDates ( ColName varchar(20), DTS datetime)
              set @sql='insert into #LocalDates select ''Created'', max(CreatedDate) from '+@LocalTable
      		exec (@sql)
              set @sql='insert into #LocalDates select ''Modified'', max(LastModifiedDate) from '+@LocalTable
      		exec (@sql)
      
      		select @MaxCreated=DTS from #LocalDates where ColName='Created'
      		select @MaxModified=DTS from #LocalDates where ColName='Modified'
      
      		drop table #LocalDates
      
              set @SQL='select * into '+@TempName+' from openquery('+@Link+',''select * from '+@Remote+' where CreatedDate>{ts'''''+convert(varchar(22),@MaxCreated,120)+'''''}'')'
              exec(@SQL)
      		exec SFAppendFromTemp @LocalTable, @TempName
      
      		set @SQL='drop table '+@TempName
      		exec (@SQL)
      
              set @SQL='select * into '+@TempName+' from openquery('+@Link+',''select * from '+@Remote+' where LastModifiedDate>{ts'''''+convert(varchar(22),@MaxModified,120)+'''''} and CreatedDate<={ts'''''+convert(varchar(22),@MaxCreated,120)+'''''}'')'
      		exec (@SQL)
              exec SFAppendFromTemp @LocalTable, @TempName
      
      		set @SQL='drop table '+@TempName
      		exec (@SQL)
      
      
          end
      create procedure SFAppendFromTemp(@Local varchar(50), @TempName varchar(50)) as 
      begin
      
      
          /* Uses the temp table to import the data into the local table making sure any duplicates are removed first */
      
          declare @Columns nvarchar(max)
          declare @ColName varchar(50)
          declare @SQL nvarchar(max)
      
          set @sql='delete from '+@Local+' where Id in ( select Id from '+@TempName+')'
          exec (@SQL)
      
          set @Columns=''
      
          declare col_cursor cursor for 
              select syscolumns.name from sysobjects inner join syscolumns on sysobjects.id = syscolumns.id where sysobjects.xtype = 'u' and  sysobjects.name = @Local
      
          open col_cursor
          fetch next from col_cursor into @ColName
          while @@FETCH_STATUS=0
          Begin
              set @Columns=@Columns+'['+@ColName+']'
              fetch next from col_cursor into @ColName
              if (@@FETCH_STATUS=0)
                  set @Columns=@Columns+', '
          End
          close col_cursor
          deallocate col_cursor
      
          set @sql='insert into '+@Local+' (' +@Columns+') select '+@Columns+' from '+@TempName
          exec (@sql)
      
      end
      
      -- Two procedures are used to get the data from a remote table. 1) SFUpdateTable, which
      -- copies the data into a temporary table. 2) SFAppendFromTemp, which appends
      -- the data from the temporary table into the local table.
      
      -- @Link Your SQL Server linked server name
      -- @Remote The name of the table within Salesforce
      -- @Local The local table where you want the data to be stored in
      -- @TempName A name of a table that can be used to temporary store data. Do not
      -- use an actual temporary table name such as #temp, this will not work.

Führen Sie zum Testen Folgendes aus:

SFUpdateTable 'SF8','Account','LocalAccount'

Dieses Beispiel kann mit jeder Salesforce-Tabelle verwendet werden, auf die ein Benutzer Zugriff hat.

Lazy-Schema-Validierung

In den Eigenschaften Ihres verknüpften SQL Server-Servers befindet sich im Abschnitt „Serveroptionen“ eine Option für „Lazy Schema Validation“. Standardmäßig ist dies auf FALSE gesetzt, was dazu führt, dass SQL Server SELECT-Anweisungen zweimal sendet. Wenn die Abfrage zum ersten Mal gesendet wird, verwendet SQL Server die zurückgegebenen Details, um Metadaten zu Ihrer Ergebnismenge zu erstellen. Dann wird die Abfrage erneut gesendet. Dies ist ein ziemlich kostspieliger Overhead, daher würde Easysoft empfehlen, dass Sie "Lazy Schema Validation" auf TRUE setzen, was bedeutet, dass nur eine Abfrage gesendet wird, die sowohl Metadaten als auch Ergebnismenge auf einmal abruft. Dadurch wird auch die Anzahl der getätigten Salesforce-API-Aufrufe eingespart.

Einschränkungen von Microsofts OLEDB für ODBC-Anbieter

Einzelheiten zu den Einschränkungen des OLEDB für ODBC-Anbieter finden Sie unter:

https://msdn.microsoft.com/en-us/library/ms719628(v=vs.85).aspx

Wie finde ich Datensätze mit einem Zeilenumbruch (newline) in der Rechnungsadresse?

Indem Sie einige der internen Funktionen des Easysoft-Treibers verwenden, können Sie leicht Datensätze finden, bei denen die Rechnungsadresse innerhalb des Datensatzes einen Zeilenvorschub hat. Zum Beispiel:

select * from openquery(sf8,'select Id, Name, {fn POSITION({fn CHAR(10)} IN BillingStreet)} LinePos from Account where {fn POSITION({fn CHAR(10)} IN BillingStreet)} >0')

POSITION(x) Diese Funktion sucht nach der Position von x innerhalb der angegebenen Spalte.

CHAR(X) Diese Funktion gibt das Zeichen mit dem ASCII-Wert x zurück .

Weitere Informationen zu den in unserem Salesforce ODBC-Treiber verfügbaren Funktionen finden Sie hier

Kann ich sehen, welche Tische über die Easysoft-Software verfügbar sind?

Führen Sie Folgendes aus, um eine Liste der Tabellen zu erhalten, auf die Sie zugreifen können:

select * from openquery(SF8,'select TABLE_NAME from INFO_SCHEMA.TABLES')

Kann ich sehen, welche Spalten über die Easysoft-Software verfügbar sind?

Sie können eine Liste der Spalten in der Tabelle abrufen, indem Sie Folgendes ausführen:

select * from openquery(SF8,'select * from INFO_SCHEMA.COLUMNS where TABLE_NAME=''Account'' ')

Mit dieser Methode erhalten Sie nur eine Liste der Spalten, die zu der Tabelle gehören, die Sie in der TABLE_NAME WHERE-Klausel angeben. Wenn Sie eine vollständige Liste der Spalten für alle Tabellen sehen möchten, führen Sie Folgendes aus:

begin
    declare @Table nvarchar(max)
	
	declare table_cursor cursor for 
        select TABLE_NAME from openquery(SF8,'select TABLE_NAME from INFO_SCHEMA.TABLES')

    open table_cursor
    fetch next from table_cursor into @Table
    while @@FETCH_STATUS=0
    Begin
		exec ('select * from INFO_SCHEMA.COLUMNS where TABLE_NAME=?', @Table) at SF8
		fetch next from table_cursor into @Table
	End

    close table_cursor
    deallocate table_cursor

end

Kann ich programmgesteuert einen Verbindungsserver erstellen?

Ja. Es gibt viele Beispiele dafür im Internet, zum Beispiel:

http://www.sqlservercentral.com/articles/Linked+Servers/142270/?utm_source=SSC