Comment puis-je utiliser un paramètre dans openquery sql, tel que:
SELECT * FROM OPENQUERY([NameOfLinkedSERVER], 'SELECT * FROM TABLENAME
where field1=@someParameter') T1 INNER JOIN MYSQLSERVER.DATABASE.DBO.TABLENAME
T2 ON T1.PK = T2.PK
sql
parameters
openquery
gaponte69
la source
la source
Réponses:
D'après la documentation OPENQUERY , il est indiqué que:
Consultez cet article pour une solution de contournement.
MISE À JOUR:
Comme suggéré, j'inclus les recommandations de l'article ci-dessous.
Passer les valeurs de base
Lorsque l'instruction Transact-SQL de base est connue, mais que vous devez transmettre une ou plusieurs valeurs spécifiques, utilisez un code similaire à l'exemple suivant:
DECLARE @TSQL varchar(8000), @VAR char(2) SELECT @VAR = 'CA' SELECT @TSQL = 'SELECT * FROM OPENQUERY(MyLinkedServer,''SELECT * FROM pubs.dbo.authors WHERE state = ''''' + @VAR + ''''''')' EXEC (@TSQL)
Passer la requête entière
Lorsque vous devez transmettre l'intégralité de la requête Transact-SQL ou le nom du serveur lié (ou les deux), utilisez un code similaire à l'exemple suivant:
DECLARE @OPENQUERY nvarchar(4000), @TSQL nvarchar(4000), @LinkedServer nvarchar(4000) SET @LinkedServer = 'MyLinkedServer' SET @OPENQUERY = 'SELECT * FROM OPENQUERY('+ @LinkedServer + ',''' SET @TSQL = 'SELECT au_lname, au_id FROM pubs..authors'')' EXEC (@OPENQUERY+@TSQL)
Utilisez la procédure stockée Sp_executesql
Pour éviter les guillemets multicouches, utilisez un code similaire à l'exemple suivant:
DECLARE @VAR char(2) SELECT @VAR = 'CA' EXEC MyLinkedServer.master.dbo.sp_executesql N'SELECT * FROM pubs.dbo.authors WHERE state = @state', N'@state char(2)', @VAR
la source
INSERT INTO @TableVariable EXEC sp_executeSql @TSQL
SELECT * FROM tab WHERE col = 'Y'
. Pour passer cette déclaration comme une chaîne à OpenQuery, toutes les guillemets simples ont besoin échappé:SELECT * FROM OPENQUERY(Server, 'SELECT * FROM tab WHERE col = ''Y'' ')
. Ensuite, pour passer le SELECT à l' aide OpenQuery à SQL dynamique, ces citations , doivent être échappés:EXEC sp_executeSQL 'SELECT * FROM OPENQUERY(Server, ''SELECT * FROM tab WHERE col = ''''Y'''' '')'
. J'espère que cela t'aides!SET @DAX = REPLACE(@DAX, '''', '''''')
Vous pouvez exécuter une chaîne avec OPENQUERY une fois que vous l'avez créée. Si vous suivez cette voie, pensez à la sécurité et veillez à ne pas concaténer le texte saisi par l'utilisateur dans votre SQL!
DECLARE @Sql VARCHAR(8000) SET @Sql = 'SELECT * FROM Tbl WHERE Field1 < ''someVal'' AND Field2 IN '+ @valueList SET @Sql = 'SELECT * FROM OPENQUERY(SVRNAME, ''' + REPLACE(@Sql, '''', '''''') + ''')' EXEC(@Sql)
la source
if
, par exemple dansif (SELECT Col1 FROM OPENQUERY('Select ...') > 0 ) BEGIN ... END
Depuis la page MSDN :
Fondamentalement, cela signifie que vous ne pouvez pas émettre de requête dynamique. Pour réaliser ce que votre échantillon tente, essayez ceci:
SELECT * FROM OPENQUERY([NameOfLinkedSERVER], 'SELECT * FROM TABLENAME') T1 INNER JOIN MYSQLSERVER.DATABASE.DBO.TABLENAME T2 ON T1.PK = T2.PK where T1.field1 = @someParameter
Il est clair que si votre table TABLENAME contient une grande quantité de données, cela ira également sur le réseau et les performances peuvent être médiocres. D'autre part, pour une petite quantité de données, cela fonctionne bien et évite les frais généraux de construction SQL dynamique (injection SQL, échappements de guillemets) qu'une
exec
approche pourrait nécessiter.la source
En fait, nous avons trouvé un moyen de le faire:
DECLARE @username varchar(50) SET @username = 'username' DECLARE @Output as numeric(18,4) DECLARE @OpenSelect As nvarchar(500) SET @OpenSelect = '(SELECT @Output = CAST((CAST(pwdLastSet As bigint) / 864000000000) As numeric(18,4)) FROM OpenQuery (ADSI,''SELECT pwdLastSet FROM ''''LDAP://domain.net.intra/DC=domain,DC=net,DC=intra'''' WHERE objectClass = ''''User'''' AND sAMAccountName = ''''' + @username + ''''' '') AS tblADSI)' EXEC sp_executesql @OpenSelect, N'@Output numeric(18,4) out', @Output out SELECT @Output As Outputs
Cela affectera le résultat de l'exécution d'OpenQuery, dans la variable @Output.
Nous avons testé la procédure Store dans MSSQL 2012, mais nous devrions travailler avec MSSQL 2008+.
Microsoft dit que sp_executesql (Transact-SQL): S'applique à: SQL Server (SQL Server 2008 jusqu'à la version actuelle), Windows Azure SQL Database (version initiale à la version actuelle). ( http://msdn.microsoft.com/en-us/library/ms188001.aspx )
la source
DECLARE @guid varchar(36); select @guid= convert(varchar(36), NEWID() ); /* The one caveat to this technique is that ##ContextSpecificGlobal__Temp should ALWAYS have the exact same columns. So make up your global temp table name in the sproc you're using it in and only there! In this example I wanted to pass in the name of a global temporary table dynamically. I have 1 procedure dropping off temporary data in whatever @TableSrc is and another procedure picking it up but we are dynamically passing in the name of our pickup table as a parameter for OPENQUERY. */ IF ( OBJECT_ID('tempdb..##ContextSpecificGlobal__Temp' , 'U') IS NULL ) EXEC ('SELECT * INTO ##ContextSpecificGlobal__Temp FROM OPENQUERY(loopback, ''Select *,''''' + @guid +''''' as tempid FROM ' + @TableSrc + ''')') ELSE EXEC ('INSERT ##ContextSpecificGlobal__Temp SELECT * FROM OPENQUERY(loopback, ''Select *,''''' + @guid +''''' as tempid FROM ' + @TableSrc + ''')') --If this proc is run frequently we could run into race conditions, that's why we are adding a guid and only deleting --the data we added to ##ContextSpecificGlobal__Temp SELECT * INTO #TableSrc FROM ##ContextSpecificGlobal__Temp WHERE tempid = @guid BEGIN TRAN t1 IF ( OBJECT_ID('tempdb..##ContextSpecificGlobal__Temp' , 'U') IS NOT NULL ) BEGIN -- Here we wipe out our left overs if there if everyones done eating the data IF (SELECT COUNT(*) FROM ##ContextSpecificGlobal__Temp) = 0 DROP TABLE ##ContextSpecificGlobal__Temp END COMMIT TRAN t1 -- YEAH! Now I can use the data from my openquery without wrapping the whole !$#@$@ thing in a string.
la source
SELECT field1 FROM OPENQUERY ([NameOfLinkedSERVER], 'SELECT field1 FROM TABLENAME') WHERE field1=@someParameter T1 INNER JOIN MYSQLSERVER.DATABASE.DBO.TABLENAME T2 ON T1.PK = T2.PK
la source
Combinez Dynamic SQL avec OpenQuery. (Cela va à un serveur Teradata)
DECLARE @dayOfWk TINYINT = DATEPART(DW, GETDATE()), @qSQL NVARCHAR(MAX) = ''; SET @qSQL = ' SELECT * FROM OPENQUERY(TERASERVER,'' SELECT DISTINCT CASE WHEN ' + CAST(@dayOfWk AS NCHAR(1)) + ' = 2 THEN ''''Monday'''' ELSE ''''Not Monday'''' END '');'; EXEC sp_executesql @qSQL;
la source
Dans l'exemple suivant, je passe un paramètre de service à une procédure stockée (spIncreaseTotalsRpt) et en même temps je crée une table temporaire à partir d'un OPENQUERY. La table Temp doit être une Temp globale (##) afin de pouvoir être référencée en dehors de son intance. En utilisant exec sp_executesql, vous pouvez passer le paramètre department.
Remarque: soyez prudent lorsque vous utilisez sp_executeSQL. De plus, votre administrateur peut ne pas avoir cette option à votre disposition.
J'espère que cela aide quelqu'un.
IF OBJECT_ID('tempdb..##Temp') IS NOT NULL /*Then it exists*/ begin DROP TABLE ##Temp end Declare @Dept as nvarchar(20) ='''47''' declare @OPENQUERY as nvarchar(max) set @OPENQUERY = 'Select ' + @Dept + ' AS Dept, * into ##Temp from openquery(SQL_AWSPROD01,''' declare @sql nvarchar(max)= @openquery + 'SET FMTONLY OFF EXECUTE SalaryCompensation.dbo.spIncreaseTotalsRpts ' + '''' + @Dept + '''' + ''')' declare @parmdef nvarchar(25) DECLARE @param nvarchar(20) SET @parmdef = N'@Dept varchar(20)' -- select @sql -- Print @sql + @parmdef + @dept exec sp_executesql @sql,@parmdef, @Dept Select * from ##Temp
Résultats
Augmentation du rayon Cnt 0 1 2 3 4 5 6 0,0000 1,0000 0,0000 0,0000 0,0000 0,0000 0,0000 0,0000
la source
J'ai trouvé un moyen qui fonctionne pour moi. Cela nécessite l'utilisation d'une table de travail à laquelle un serveur lié a accès.
J'ai créé une table et l'ai remplie avec les valeurs dont j'ai besoin, puis je référence cette table via un serveur lié.
SELECT * FROM OPENQUERY(KHSSQLODSPRD,'SELECT * FROM ABC.dbo.CLAIM A WITH (NOLOCK) WHERE A.DOS >= (SELECT MAX(DATE) FROM KHSDASQL01.DA_MAIN.[dbo].[ALLFILENAMES]) ')
la source
declare @p_Id varchar(10) SET @p_Id = '40381' EXECUTE ('BEGIN update TableName set ColumnName1 = null, ColumnName2 = null, ColumnName3 = null, ColumnName4 = null where PERSONID = '+ @p_Id +'; END;') AT [linked_Server_Name]
la source
openquery
devrait également connaître cette approche. C'est aussi beaucoup plus propre. Donc +1 de mon côté.Nous pouvons utiliser
execute
method au lieu deopenquery
. Son code est beaucoup plus propre. J'ai dû obtenirlinked server
le résultat de la requête dans une variable. J'ai utilisé le code suivant.CREATE TABLE #selected_store ( code VARCHAR(250), id INT ) declare @storeId as integer = 25 insert into #selected_store (id, code) execute('SELECT store_id, code from quickstartproductionnew.store where store_id = ?', @storeId) at [MYSQL] declare @code as varchar(100) select @code = code from #selected_store select @code drop table #selected_store
Remarque:
la source
Exemple simple basé sur l'exemple de @Tuan Zaidi ci-dessus qui semblait le plus simple. Je ne savais pas que vous pouviez faire le filtre à l'extérieur d'OPENQUERY ... tellement plus facile!
Cependant, dans mon cas, j'avais besoin de le remplir dans une variable, j'ai donc créé un niveau de sous-requête supplémentaire pour renvoyer une valeur unique.
SET @SFID = (SELECT T.Id FROM (SELECT Id, Contact_ID_SQL__c FROM OPENQUERY([TR-SF-PROD], 'SELECT Id, Contact_ID_SQL__c FROM Contact') WHERE Contact_ID_SQL__c = @ContactID) T)
la source