sql >> Databáze >  >> RDS >> Sqlserver

Tipy pro používání SQL Serveru se Salesforce

Obsah

  1. Přehled
  2. Klauzule WHERE
  3. Spojení více stolů
  4. Místní stůl připojený ke vzdálenému stolu
  5. Vložit, aktualizovat a smazat
  6. Aktualizovat
  7. Aktualizovat pomocí parametrů
  8. Vložení nového záznamu a získání chyby BLOB
  9. Získání ID Salesforce pro poslední vložený záznam
  10. Aktualizace dat SQL Server při změně dat Salesforce
  11. Ověření líného schématu
  12. Omezení OLEDB společnosti Microsoft pro poskytovatele ODBC
  13. Jak najdu záznamy s odřádkováním (nový řádek) ve fakturační adrese?
  14. Mohu vidět, které tabulky jsou dostupné prostřednictvím softwaru Easysoft?
  15. Mohu vidět, které sloupce jsou dostupné prostřednictvím softwaru Easysoft?
  16. Mohu programově vytvořit propojený server?

Přehled

Tento dokument poskytuje několik tipů, jak používat SQL Server se Salesforce. Komponenty používané k připojení SQL Server k Salesforce jsou SQL Server Linked Server a Easysoft Salesforce ODBC Driver. Jak připojíte SQL Server k Salesforce, je popsáno v tomto článku. V příkladech v tomto dokumentu je použitý název propojeného serveru (na který odkazujete v příkazech SQL) SF8.

Všechny SQL v tomto dokumentu byly testovány s SQL Server 2017 a ovladačem Easysoft Salesforce ODBC verze 2.0.0 až 2.0.7.

Funkce SQL Serveru OPENQUERY a EXEC (EXECUTE ) byly zavedeny do SQL Server 2008 a tyto funkce jsou kompatibilní se všemi verzemi SQL Serveru po roce 2008.

Tento dokument jsme napsali jako odpověď na řadu dotazů, které obdržel náš tým podpory ohledně připojení SQL Serveru přes Easysoft k Salesforce. Příklady SQL by však měly být užitečné také pro připojení k Linked Server, která používají jiný ovladač ODBC a backend.

Pokud byste chtěli přispět k tomuto dokumentu, zašlete svůj příspěvek e-mailem na adresu .

Klauzule WHERE

Častým problémem, který nám byl hlášen, je „jednoduchá klauzule WHERE trvá dlouho, než vrátí pouze jeden řádek“. Například:

vyberte Id, FirstName, LastName z SF8.SF.DBO.Contact kde Id='00346000002I95MAAS'

SQL Server převede výše uvedený dotaz a odešle jej do ovladače Salesforce ODBC:

vyberte Id, First Name, LastName z SF.DBO.Contact

Klauzule WHERE je vždy odebrána, což přinutí ovladač ODBC vrátit všechny řádky pro danou tabulku. Potom je SQL Server filtruje lokálně, aby vám poskytl požadované řádky. Zdá se, že nezáleží na tom, jakou klauzuli WHERE jste zadali, nikdy to není předáno ovladači ODBC.

Jednoduchým řešením je použít SQL Server OPENQUERY místo toho funkci. Například:

vyberte * z OPENQUERY(SF8,'select Id, First Name, LastName from SF.DBO.Contact where Id=''00346000002I95MAAS'' ')

Všechny SQL, které spustíte v OPENQUERY funkce je předána přímo ovladači, včetně WHERE doložka.

Spojení více stolů

Zde je jednoduché spojení dvou tabulek, kde se obě tabulky vracejí z propojeného serveru.

vyberte a.[Name], BillingStreet, c.[Name] z SF8.SF.DBO.Account a, SF8.SF.DBO.Contact c kde a.Id=c.AccountID a [Name] jako 'United %'

SQL Server odešle následující dotazy na ovladač ODBC.

vyberte * z účtuvyberte * z kontaktu

SQL Server to dělá, aby získal seznam názvů sloupců a datových typů. Poté pokračuje odesláním těchto dotazů do ovladače ODBC.

SELECT "Tbl1001"."Id" "Col1042","Tbl1001"."Name" "Col1044","Tbl1001"."BillingStreet" "Col1046" FROM "SF"."DBO"."Účet" "Tbl1001" " ORDER BY "Col1042" ASCSELECT "Tbl1003"."AccountId" "Col1057","Tbl1003"."Name" "Col1058" FROM "SF"."DBO"."Contact" "Tbl1003" ORDER BY "Col1057" ASC /před> 

Data z obou dotazů se vrátí do lokálních tabulek, poté se do tabulky Account umístí klauzule WHERE a data z obou tabulek se spojí a vrátí.

Opět použití OPENQUERY zajišťuje, že zapsané SQL bude předáno přímo ovladači ODBC, takže místo toho byste na serveru SQL spustili:

vyberte * z OPENQUERY(SF8,'select a.[Jméno], BillingStreet, c.[Název] z SF.DBO.Account a, SF.DBO.Contact c kde a.Id=c.AccountID aa. [Název] jako ''United%'' ')

Potřebujete drobnou úpravu, protože SQL Server nedokáže zpracovat více sloupců se stejným "Název", takže musíte jeden z těchto sloupců přejmenovat. Například:

vyberte * z OPENQUERY(SF8,'select a[Name], BillingStreet, c.[Name] jako FullName z SF.DBO.Account a, SF.DBO.Contact c kde a.Id=c.AccountID and a.[Name] jako ''United%'' ')

To přinutí ovladač ODBC zpracovat celý SQL najednou a vrátit pouze požadované výsledky.

Místní stůl připojený ke vzdálenému stolu

V tomto příkladu byla místní tabulka vytvořena spuštěním.

vyberte * do LocalAccount z SF8.SF.DBO.Account

Spojení dvou tabulek nyní vypadá takto.

vyberte a.[Name], BillingStreet, c.[Name] jako FullName z LocalAccount a, SF8.SF.DBO.Contact c kde a.Id=c.AccountID a [Name] jako 'United%' 

To způsobí, že SQL Server třikrát odešle následující dotaz na ovladač ODBC.

vyberte * z kontaktu

Alespoň v jednom z těchto dotazů SQL Server požaduje všechna data v tabulce. Potom SQL Server pokračuje v dotazu:

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

SQL Server pak předá ovladači ODBC seznam AccountIds z tabulky LocalAccount namísto "?" kde sloupec LocalAccount.[Name] odpovídá klauzuli LIKE.

Rychlejší způsob, kde je tabulka ODBC druhou tabulkou v dotazu, je získat z tabulky ODBC pouze ty sloupce, které potřebujete. To lze provést pomocí OPENQUERY funkce. Například:

vyberte a.[Name], BillingStreet, c.[Name] jako FullName z LocalAccount a, openquery(SF8,'select [Name], AccountId from SF.DBO.Contact') c kde a.Id=c. AccountID a [Name] jako 'United%'

I když to stále získává všechny řádky z tabulky kontaktů, získává pouze potřebné sloupce, a je proto rychlejší než standardní dotaz.

Dalším možným způsobem by bylo použití kurzoru a dočasné tabulky. Například:

Začněte deklarovat @AccountId jako varchar(20) deklarujte @SQL jako varchar(1024) -- Vytvořte dočasnou tabulku pro uložení informací o účtu. Kontrola Id zajišťuje, že se vrátí 0 řádků dat select * do #LocalContact z openquery(SF8,'select [Name], AccountId from SF.DBO.Contact where Id=''000000000000000000'' ') -- Nastavte deklaraci kurzoru selcur kurzor pro výběr odlišného ID z LocalAccount, kde [Name] jako 'United%' otevírá selcur načtení další ze selcur do @AccountId, zatímco @@FETCH_STATUS=0 Začít vybrat @SQL ='vložit do #LocalContact vybrat [Name], ''' +@AccountId+''' z OPENQUERY(SF8,''vyberte [Jméno] z kontaktu, kde AccountId=''''' + @AccountId + ''''' '')' exec (@SQL) dále načte ze selcur do @AccountId Konec zavřít selcur deallocate selcur -- Dále připojte své tabulky a zobrazte data, vyberte a.[Name], BillingStreet, c.[Name] jako Celé jméno z LocalAccount a, #LocalContact c kde a.Id=c.AccountID a a.[Name] jako 'United%' -- Nezapomeňte odstranit dočasnou kartu přetáhněte tabulku #LocalContact End

Tato metoda může být několikrát rychlejší než OPENQUERY metoda uvedená v předchozím příkladu, pokud klauzule WHERE předávaná ovladači Easysoft ODBC používá index v Salesforce.

Vložit, aktualizovat a smazat

Pokud spouštíte dotaz, který není dotazem SELECT, pak nejlepším způsobem, jak toho dosáhnout, je použít SQL Server EXEC funkce. Pokud váš propojený server nemůže použít EXEC , dostanete zprávu podobnou:

Server 'SF8' není nakonfigurován pro RPC.

Chcete-li použít EXEC , klikněte pravým tlačítkem na váš propojený server a vyberte vlastnosti. V sekci "Možnosti serveru" nastavte "RPC Out" na "True". Poté můžete použít EXEC funkce.

Aktualizovat

Řekněme, že máte tento příkaz v SQL Server:

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

SQL Server odešle tento SQL ovladači ODBC.

vyberte * z "SF"."DBO"."Kontakt"

Všechny záznamy jsou načteny a SQL Server poté odešle tento příkaz ovladači ODBC.

UPDATE "SF"."DBO"."Contact" SET "LastName"=? KDE "ID"=? AND "LastName"=?

SQL Server to dělá, aby zajistil, že se záznam nezmění v době mezi spuštěním dotazu a provedením UPDATE. Rychlejší metodou je použít SQL Server EXEC funkce. Například:

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

SQL Server odešle ovladači ODBC celý řetězec, který jste zadali, takže dotaz se provede bez výběru celé tabulky.

Aktualizovat parametry

Řekněme, že máte:

Začněte deklarovat @Id varchar(20)='00346000002I95MAAS' deklarovat @LastName varchar(20)='James' update SF8.SF.DBO.Contact set LastName=@LastName where Id=@IdEnd

Funguje to přesně stejným způsobem, jak je popsáno v poznámkách k aktualizaci. Nicméně syntaxe při použití EXEC změny funkcí:

Začněte deklarovat @Id varchar(20)='00346000002I95MAAS' deklarujte @LastName varchar(20)='James' exec ('update SF.DBO.Contact set LastName=? where Id=?', @LastName, @Id ) na SF8End

Kde máte sloupec jako LastName= vložíte ? místo @LastName reprezentovat to, co se chystáte předat do parametru. Parametry jsou pak uvedeny za příkazem UPDATE v pořadí, ve kterém je třeba je číst.

Vložení nového záznamu a získání chyby BLOB

Řekněme, že se pokoušíte spustit:

vložte do SF8.SF.DBO.Contact ( jméno, příjmení ) hodnoty ('Easysoft','Test')

SQL Server to odešle ovladači ODBC:

vyberte * z "SF"."DBO"."Kontakt"

To se provádí dvakrát. Při prvním spuštění SQL Server kontroluje, zda je výsledková sada aktualizovatelná. Při druhém odeslání se SQL Server přesune na prázdný záznam poté, co se vrátí poslední záznam, a pokusí se provést poziční INSERT, což způsobí chybu.

Poskytovatel OLE DB "MSDASQL" pro propojený server "SF8" vrátil zprávu "Vkládání nebo aktualizace hodnot BLOB na základě dotazu není podporováno.".

Tato zpráva je vrácena, protože poziční vložka se pokouší vložit všechny sloupce s hodnotami NULL kromě těch, které jste zadali v příkazu INSERT, a v případě tabulky Contact existuje BLOB (dlouhá textová oblast v Salesforce), které poskytovatel OLE DB od společnosti Microsoft nepodporuje. Ovladač Easysoft Salesforce ODBC podporuje vkládání všech polí v rámci Salesforce, kde máte oprávnění vkládat data. Chcete-li to obejít, vše, co musíte udělat, je použít EXEC.

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

Toto pouze odešle INSERT přímo do ovladače ODBC.

Získání ID Salesforce pro poslední vložený záznam

Několik našich zákazníků se nás zeptalo, jaký je nejjednodušší způsob, jak získat ID právě vloženého řádku. Tento příklad ukazuje, jak můžete získat ID posledního záznamu, který jste vložili do tabulky "Kontakt".

Začněte deklarovat @Id varchar(20)='00346000002I95MAAS' deklarujte @FirstName varchar(20)='Easysoft' deklarujte @LastName varchar(20)='Test' deklarujte @FindTS varchar(22)=convert(varchar(22) ),GETUTCDATE(),120) deklarovat @SQL jako varchar(1024) exec ('vložit do SF.DBO.Contact (FirstName, LastName ) values ​​(?, ?)', @FirstName, @LastName ) v SF8 vybrat @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+''' ''} a c.CreatedById=u.Id pořadí podle c.CreatedDate desc'')' exec (@SQL) End

Když je záznam vytvořen v Salesforce, sloupec „CreatedDate“ obsahuje časové razítko, které je UTC (Coordinated Universal Time), kdy byl záznam vytvořen, a nemusí nutně obsahovat vaše aktuální datum/čas. @FindTs řetězec je nastaven na UTC předtím, než dojde k INSERT, takže když je volán SELECT pro získání Id, dívá se pouze na řádky vložené za @FindTS byla nastavena.

Během SELECT se Easysoft CURRENT_USER Funkce se také používá k omezení řádků vrácených ze Salesforce pouze na uživatele, který vložil data.

Aktualizace dat SQL Server při změnách dat Salesforce

Tato část ukazuje, jak vytvořit novou tabulku SQL Serveru na základě struktury tabulky Salesforce a aktualizovat tuto tabulku, když v této tabulce Salesforce dojde ke změnám.

vytvořit proceduru SFMakeLocal( @Link varchar(50), @Remote varchar(50), @Local varchar(50), @DropLocal int) jako deklarovat @SQL jako nvarchar(max) begin /* Importuje data do místního tabulka */ /* Nastavte DropLocal na 1 pro zrušení lokální tabulky, pokud existuje */ if OBJECT_ID(@Local, 'U') NENÍ NULL begin if (@DropLocal=1) begin set @SQL='DROP TABLE dbo. '+@Local exec ( @SQL) end else RAISERROR(15600,1,1, 'Místní tabulka již existuje') RETURN end set @SQL='vyberte * do dbo.'+@Local+' z OPENQUERY('+@Link+ ',''select * from '+@Remote+''')' exec(@SQL) select 'Local Table :'+@Local+' created.' end -- @Link Your SQL Server propojený server -- @Remote Název tabulky v rámci Salesforce -- @Local Místní tabulka, do které chcete data ukládat -- @DropLocal Nastavte na 1, pokud tabulka existuje a chcete zahodit to

Spusťte postup pro zkopírování struktury záznamu z tabulky Salesforce do místní tabulky a poté přeneste všechna data Salesforce. Tento příklad příkazu používá tabulku účtů. Tento proces může chvíli trvat v závislosti na množství dat, která máte v tabulce Salesforce.

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

Argumenty jsou:

Argument Hodnota
SF8 Název propojeného serveru SQL Server.
Účet Název tabulky Salesforce, který chcete použít ke čtení struktury a dat.
Místní účet Název vaší tabulky na serveru SQL.
0 Tuto výchozí hodnotu lze změnit na 1, pokud do Salesforce přidáte další vlastní sloupce a chcete zrušit místní tabulku a vytvořit ji znovu s novými sloupci.

Dalším krokem je vytvoření dvou dalších procedur, které aktualizují místní tabulku, pokud budou nějaká data aktualizována nebo vložena do tabulky Salesforce:

vytvořit proceduru SFUpdateTable ( @Link varchar(50), @Remote varchar(50), vytvořit proceduru SFUpdateTable @Link varchar(50), @Remote varchar(50), @LocalTable varchar(50) as begin -- Aktualizuje data do místní tabulky na základě změn v Salesforce. deklarovat @TempDef jako varchar(50)='##EasyTMP_' deklarovat @TempName jako varchar(50) deklarovat @TempNumber jako desetinné deklarovat @CTS jako datetime=current_timestamp deklarovat @TTLimit int =100 deklarovat @MaxCreated jako datetime deklarovat @MaxModified jako datetime deklarovat @SQL jako nvarchar(max) deklarovat @RC jako int -- Prvním krokem je vytvoření globální dočasné tabulky. set @TempNumber=datepart(yyyy,@CTS)*10000000000 +datum(mm,@CTS)*100000000+datum(dd,@CTS)*1000000+datum(hh,@CTS)*10000+datum(mi,@CTS)*100+datum(ss,@CTS) nastavit @ TempName=@TempDef+cast(@TempNumber jako varchar(14)) zatímco OBJECT_ID(@TempName, 'U') NENÍ NULL begin RAISERROR (15600,1,1, 'Název Temp se již používá.') RETURN end set @SQL='vyberte * do '+@TempName+' z '+@ LocalTable+' kde 1=0' vytvořit tabulku #LocalDates ( ColName varchar(20), datum a čas DTS) nastavit @sql='vložit do #LocalDates vybrat ''Created'', max(CreatedDate) z '+@LocalTable exec (@sql ) nastavit @sql='insert into #LocalDates vybrat ''Modified'', max(LastModifiedDate) z '+@LocalTable exec (@sql) vybrat @MaxCreated=DTS z #LocalDates kde ColName='Created' vybrat @MaxModified=DTS from #LocalDates where ColName='Modified' drop table #LocalDates set @SQL='select * do '+@TempName+' from openquery('+@Link+',''select * from '+@Remote+' where CreatedDate>{ts '''''+convert(varchar(22),@MaxCreated,120)+'''''}'')' exec(@SQL) exec SFAppe ndFromTemp @LocalTable, @TempName set @SQL='drop table '+@TempName exec (@SQL) set @SQL='select * do '+@TempName+' z openquery('+@Link+',''select * from ' +@Remote+' kde LastModifiedDate>{ts'''''+convert(varchar(22),@MaxModified,120)+'''''} a CreatedDate<={ts'''''+convert(varchar( 22),@MaxCreated,120)+'''''}'')' exec (@SQL) exec SFAppendFromTemp @LocalTable, @TempName set @SQL='drop table '+@TempName exec (@SQL) end procedura vytvoření SFAppendFromTemp(@Local varchar(50), @TempName varchar(50)) as begin /* Použije dočasnou tabulku k importu dat do místní tabulky a ujistěte se, že jsou nejprve odstraněny všechny duplikáty */ deklarovat @Columns nvarchar(max) deklarovat @ ColName varchar(50) deklaruje @SQL nvarchar(max) set @sql='delete from '+@Local+' kde Id in (vyberte Id z '+@TempName+')' exec (@SQL) set @Columns='' deklarovat kurzor col_cursor pro výběr syscolumns.name z vnitřního spojení syscolumns sysobjects na sysobjects.id =syscolumns.id kde sysobjects.xtype ='u' a sysobjects.name =@Local otevřít col_cursor načtení jako další z col_cursor do @ ColName while @@FETCH_STATUS=0 Začít nastavit @Columns=@Columns+'['+@ColName+']' načíst další z col_cursor do @ColName, pokud (@@FETCH_STATUS=0) nastavit @Columns=@Columns+', ' Konec zavřít col_cursor deallocate col_cursor set @sql='insert into '+@Local+' (' +@Columns+') select '+@Columns+' z '+@TempName exec (@sql) end -- K získání dat z a vzdálený stůl. 1) SFUpdateTable, který -- zkopíruje data do dočasné tabulky. 2) SFAppendFromTemp, který připojí -- data z dočasné tabulky do lokální tabulky. -- @Link Your SQL Server název propojeného serveru -- @Remote Název tabulky v rámci Salesforce -- @Local Lokální tabulka, do které chcete ukládat data -- @TempName Název tabulky, kterou lze použít k dočasnému uložení dat. Ne -- použijte skutečný název dočasné tabulky, například #temp, to nebude fungovat.

Chcete-li to vyzkoušet, spusťte:

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

Tento příklad lze použít s jakoukoli tabulkou Salesforce, ke které má uživatel přístup.

Ověření líného schématu

Ve vlastnostech propojeného serveru SQL Server je v části "Možnosti serveru" možnost "Ověření líného schématu". Ve výchozím nastavení je toto nastaveno na FALSE, což způsobí, že SQL Server odešle příkazy SELECT dvakrát. Při prvním odeslání dotazu SQL Server použije podrobnosti předané zpět k vytvoření metadat o vaší sadě výsledků. Poté je dotaz odeslán znovu. To je poměrně drahá režie, takže Easysoft doporučuje nastavit "Lazy Schema Validation" na hodnotu TRUE, což znamená, že se odešle pouze jeden dotaz a načte metadata i sadu výsledků najednou. Tím se také ušetří počet uskutečněných volání rozhraní Salesforce API.

Omezení OLEDB společnosti Microsoft pro poskytovatele ODBC

Podrobnosti o omezeních OLEDB pro poskytovatele ODBC naleznete na adrese:

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

Jak najdu záznamy s odřádkováním (nový řádek) ve fakturační adrese?

Pomocí některých interních funkcí ovladače Easysoft můžete snadno najít záznamy, kde má fakturační adresa v záznamu řádek. Například:

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) Tato funkce hledá pozici x v zadaném sloupci.

CHAR(X) Tato funkce vrací znak s hodnotou ASCII x .

Více informací o funkcích dostupných v našem Salesforce ODBC ovladači naleznete zde

Mohu vidět, které tabulky jsou dostupné prostřednictvím softwaru Easysoft?

Chcete-li získat seznam tabulek, ke kterým máte přístup, spusťte:

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

Mohu vidět, které sloupce jsou dostupné prostřednictvím softwaru Easysoft?

Seznam sloupců, které jsou v tabulce, získáte spuštěním:

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

Pomocí této metody můžete získat pouze seznam sloupců, které patří do tabulky, kterou zadáte v klauzuli TABLE_NAME WHERE. Pokud chcete zobrazit úplný seznam sloupců pro všechny tabulky, spusťte:

začněte deklarovat @Table nvarchar(max) deklarujte kurzor table_cursor pro výběr TABLE_NAME z openquery(SF8,'select TABLE_NAME z INFO_SCHEMA.TABLES') otevřete načtení table_cursor další z table_cursor do @Table, zatímco @@FETCH_STATUS=0 Begin exec (' vybrat * z INFO_SCHEMA.COLUMNS kde TABLE_NAME=?', @Table) na SF8 načíst další z table_cursor do @Table End close table_cursor deallocate table_cursorend

Mohu programově vytvořit propojený server?

Ano. Na webu je k tomu spousta příkladů, například:

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


  1. Jak YEAR() funguje v MariaDB

  2. Jak vytvořit tabulku s omezením cizího klíče v SQL Server - SQL Server / TSQL výukový program, část 66

  3. SQL Server ALL operátor vysvětlen

  4. Jak vypočítat rozdíl mezi dvěma časovými razítky v PostgreSQL