Fragensteller
SQL Server - Job Agent - Query Linkedserver

Allgemeine Diskussion
-
Sehr geehrte Damen und Herren,
ich habe mal eine Frage bezüglich einer T-SQL Abfrage im Job. Im Query wird auf einen Verbindungsserver Daten abgefragt! Der Query funktioniert auch einwandfrei, wenn ich den manuell ausführe. Wenn ich aber den Job ausführe, erhalten ich folgende Meldung.
Ausgeführt als Benutzer:"Domäne\BENUTZER". Falsche Syntax in der Nähe von "LINKEDSERVER"...
Ich habe den SQL Server Agent auch mal einen Domänen\Benutzer zugewiesen. Meldung kommt trotzdem noch.
Hat jemand vill eine Idee, wie ich das Problem beheben kann oder kann mir Tipps geben?
Gruß
- Typ geändert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 9. März 2018 15:59 Warten auf Rückmeldung
Alle Antworten
-
a) kommt es auf die Art der Abfrage an: "Select * from LinkedServer.Database.Schema.Table" oder "select * from OpenQuery('LinkedServer', 'Select * from Table')".
b) Logon-Informationen für einen Linked-Server sollte man der Einfachheit wegen in die dortige Konfiguration schreiben. Ggf. kommt es hier zum Konflikt da keine Anmeldung erfolgt ist.
-
Normalerweise muss man sich auch bei LinkedServer an der Zieldatenbank anmelden.
Diese Anmeldung kann man statisch in der Konfiguration hinterlegen (User/Kennwort), so dass keine individuelle Anmeldung erfolgen muss.
Diese Anmeldung erfolgt häufig durch den Treiber selber, der u.U. diese Anmeldung auch cached.
Deshalb klappts eben im Dialog, aber nicht im Batch, da ja da keiner für die Anmeldung da ist. -
Lokale Anmeldungen machst du ja mit deinem Script/Programm.
Beim LinkedServer kann man eben je lokaler Anmeldung eine individuelle Remoteanmeldung und eben eine Default-Anmeldung hinterlegen.Ansonsten hat meine Erfahrung gezeigt, dass es besser ist per OpenQuery() oder EXEC (Non-Queries) auf LinkedServer (außer wenn es ein entfernter SQL-Sever ist) zuzugreifen, da es sonst u.U. zu SQL-Dialektproblemen kommt.
-
Ja gut, dass habe ich ja gemacht, jedoch hat es mir keinen Erfolg gebracht.OpenQuery() habe ich auch schon probiert.
SELECT * FROM OpenQuery(LinkedServer, ' DELCARE var1 INT, var2 INT SET var1 = Wert1 SET var2 = Wert2 SELECT COUNT(var1 + var2) ')
Funkioniert so nicht. Habe das Gefühl das er nicht mit Variablen arbeiten kann. Stimmt das? Bin halt noch blutiger Anfänger.
-
Nun, was du da abgibst hat nicht entfernt mit SQL zu tun.
Das ist irgendeine rudimentäre Geschichte aus SQL-Script u.a.Wenn du einen LinkedServer zu einer DB hast, machdoch erst mal einen
select * from OpenQuery(LinkedServer, 'select * from MyTable')
wobei MyTable eine dir bekannte Tabelle im Zielserver sein muss.
-
Habe das mal mit einer normalen Abfrage getestet ohne jeglichen schnick schnack!
Wenn ich das wieder direkt ausführe, klappt es einwandfrei. Jedoch wenn ich das über den Trigger laufen lasse als Job geht es nicht.
Habe aber diesmal eine bessere Fehlermeldung bekommen:
Meldung "208",Ebene "16", Status "1", Server "LinkedServer" ....
"Anweisung konnte nicht vorbereitet werden." Der OLE DB-Anbieter "SQLNCLI11" für den Verbindungsserver hat die Meldung "Die verzögerte Bereitstellung konnte nicht beendet werden." zurückgegeben.
-
Poste doch mal das Statement!
Vermeide außerdem möglichst ein "Select *"!
Wie bereits erwähnt ist die Verwendung mit OpenQuery sicherer in der Handhabung!
Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu
-
Ein einfaches Beispiel der Inkompatibilität:
Im SQL-Server werden Namen, deren Konvention nicht eingehalten werden, in eckige Klammern gesetzt.
Im SQL-Standard sind das Anführungszeichen:SQL-Server: select [Artikel-Nr] from [Artikel-Stamm]
SQL-Standard: Select "Artikel-Nr" from "Artikel-Stamm"Verwendest du nun einen "Select * from VerbServer.DB.Schema.Table" wird vom SQL-Server das Schema abgefragt um die Felder zu erhalten und den Select umzubauen.
Hat die Quelltabelle nun ungültige Namen, so setzt der SQL-Server diese in eckige Klammern, da Microsoft der Meinung ist, jeder andere SQL-Anbieter hat dies so zu verstehen.
Versteht der VerbServer aber keine eckigen Klammern, so wird der SQL wegen Dialekt-Fehler abgewiesen (keine Vorbereitung ....).Anders bei OpenQuery:
select [Artikel-Nr] from OpenQuery(VerbServer, 'select "Artikel-Nr" from MyTable') funktioniert hingegen. Ebenso auch ein "select * ", da die Schemaabfrage nun nur noch auf das Ergebnis des OpenQuery geht und die eckigen Klammern nicht durchgeroutet werden.
Das selbe gilt auch für viele SQL-Funktionen wie z.B. Substring(), Upper(), Lower() usw., da diese durchaus je SQL-Dialekt unterschiedlich heißen, aufgebaut sind oder gar nicht vorhanden sind.
Der SQL-Standard gibt diesbezüglich leider sehr wenig her.
Daher:
Bei Verbindungsservern (nicht Microsoft SQL-Server) sollte man grundsätzlich OpenQuery() und EXEC 'Native SQL' on VerbServer verwenden, alles andere führt unweigerlich zu diversen Problemen. -
Habe jetzt nochmal einfachshalber folgende Querys probiert, die über den Job Agent nicht laufen, aber beide normal funktionieren.
SELECT * FROM OPENQUERY([LinkedServer],'SELECT * FROM [dbo].[TabellenName]') > die lange Fehlermeldung wie oben beschrieben
SELECT * FROM OPENQUERY("LinkedServer",'SELECT * FROM "dbo"."TabellenName"') > Fehlermeldung: Falsche Synthax
-
Dann ist dein LinkedServer ja ein SQL-Server und das Syntaxproblem sollte ja nicht bestehen.
Vielleicht schaust du dir das noch mal genauer an:
https://docs.microsoft.com/de-de/sql/relational-databases/linked-servers/create-linked-servers-sql-server-database-engine
-
Den Link von bfuerchau habe ich mir auch schon angeschaut.
Habe sogar schon MS DTC aktiviert lt. der Anleitung:
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc753510(v=ws.10)
Das leider auch alles ohne Erfolg. Ich weiß echt nicht mehr weiter. Irgendwas muss ich übersehen haben..
-
Meiner Meinung nach liegt der Fehler bei der Anlage des LinkedServers. Normalerweise ist der Name des Verbindungsservers auch der Netzwerkname des Servers.
Also bitte noch mal neu und korrekt anlegen, dann sollte es eigentlich funktionieren.
Ich kann mir nicht vorstellen, dass die Maschine "LinkedServer" heißt.
USE [master] GO EXEC master.dbo.sp_addlinkedserver @server = N'<Netzwerkname>', @srvproduct=N'SQL Server' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'collation compatible', @optvalue=N'false' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'data access', @optvalue=N'true' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'dist', @optvalue=N'false' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'pub', @optvalue=N'false' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'rpc', @optvalue=N'false' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'rpc out', @optvalue=N'false' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'sub', @optvalue=N'false' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'connect timeout', @optvalue=N'0' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'collation name', @optvalue=null GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'lazy schema validation', @optvalue=N'false' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'query timeout', @optvalue=N'0' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'use remote collation', @optvalue=N'true' GO EXEC master.dbo.sp_serveroption @server=N'<Netzwerkname>', @optname=N'remote proc transaction promotion', @optvalue=N'true' GO USE [master] GO EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N'<Netzwerkname>', @locallogin = NULL , @useself = N'True' GO
Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu
- Bearbeitet Christoph Muthmann Freitag, 23. Februar 2018 08:17
-
Ich habe jetzt mal mit deinem Script den Verbindungsserver angelegt.
Jetzt bekomme ich schon bei einer normalen Abfrage folgende Fehlermeldung:
Der OLE DB-Anbieter "SQLNCLI11" für den Verbindungsserver "<Netzwerkname(LinkedServer)>" hat die Meldung "Die verzögerte Bereitstellung konnte nicht beendet werden." zurückgeben. Meldung 8180, Ebene 16, Status 1, Zeile 1 Anweisung(en) konnte(n) nicht vorbereitet werden. Meldung 208, Ebene 16, Status 1, Zeile 1 Ungültiger Objektname 'dbo.<Tabellenname>'.
Genau die selbe Abfrage hat, jedoch vorher normal funktioniert gehabt.
-
Also normalerweise ist der Name des LinkedServer's vollkommen egal, da man über die Verbindungseigenschaften einen Treiber (OLEDB) oder ODBC (ggf. mit DSN-Konfiguration) sowie gezielt mit einer Datenbank verbindet.
Bei nativen SQL's per OpenQuery ist dann also der Name der DB nicht mehr anzugeben, da man ja bereits mit der DB verbunden ist.
Nun gibt es noch die Möglichkeit, innerhalb einer DB mehrere Schemas einzurichten, was quasi wie eine DB in einer DB wäre. Dann müssten Tabellen mit "Schemaname.TableName" referenziert werden.
I.d.R. wird aber beim SQL-Server nicht mit Schemas gearbeitet und soweit ich weiß ist "dbo" der Name einer Datenbank auf dem SQL-Server.Nun kommt es also noch mal darauf an, wie du deinen Linked Server konfiguriert hast.
Außerdem habe ich auch schon festgestellt, dass man mache Treiber nur "Out of Process" verwenden kann (Konfiguration).
-
Das dazugehörige SQL wäre schon noch interessant gewesen. Hast Du auch den Datenbank-Namen im SQL mit aufgeführt?
Der Verbindungsserver stellt nur die Verbindung zum Server her und Du landest in der Default-Database des aktuellen Kontos. Für andere Datenbanken solltest Du dann die dreiteilige Syntax verwenden: Datenbank.Schema.Objektname
Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu