2009-10-12 4 views
3

J'ai une requête MS SQL qui extrait des données via un serveur distant. Les données que je tire vers le bas doit être filtré par une date qui est déterminée au moment de l'exécution .. Quand je lance la requête comme ceci:Forcer une requête SQL Remote à filtrer à distance au lieu de

SELECT * FROM SERVER.Database.dbo.RemoteView 
WHERE EntryDate > '1/1/2009' 

alors le filtre est appliqué à distance ... Cependant, je ne veulent pas réellement utiliser « 1/1/2009 » comme la date - je veux la date à fournir par une fonction définie par l'utilisateur, comme ceci:

SELECT * FROM SERVER.Database.dbo.RemoteView 
WHERE EntryDate > dbo.MyCustomCLRDateFunction() 

où la fonction est un scalaire CLR personnalisé -valued fonction qui renvoie une date et heure ... (Vous pouvez demander pourquoi j'ai besoin de faire cela ... les détails sont un peu compliqués, alors faites-moi confiance - je dois le faire de cette façon)

Lorsque j'exécute cette requête, la requête distante n'est PAS filtrée à distance - le filtrage est effectué après que toutes les données ont été supprimées (400 000 lignes contre 100 000 lignes) et cela fait une différence significative.

Existe-t-il un moyen de forcer la requête à effectuer le filtrage à distance?

Merci!

Répondre

1

Vous ne pouvez pas simplement envoyer une requête comme celle-ci ou la fonction clr doit-elle être appelée dans l'instruction select?

Declare @datetime datetime 
Set @datetime = dbo.MyCustomCLRDateFunction() 

SELECT * FROM SERVER.Database.dbo.RemoteView 
WHERE EntryDate > @datetime 
+0

Vous savez ce qui est drôle? Cette même solution a été suggérée par un autre utilisateur, mais j'ai dit que je ne pouvais pas le faire parce que la requête est en fait construite dynamiquement par une couche de données WTF qui choisit les colonnes qu'elle veut voir, comment grouper les données, trier, etc. ... Je ne pensais pas que j'allais pouvoir utiliser cette réponse parce que tout est exécuté comme une requête construite. Mais en y regardant de plus près, je pense que j'ai à peine assez de flexibilité dans la façon dont il a été conçu pour que cette solution fonctionne. Dans les tests, il semble certainement fonctionner. –

+1

OK, donc j'ai implémenté avec succès dans l'environnement de développement ... Comme je le pensais, le système WTF avait juste assez de flexibilité que j'ai pu obtenir ce type de code inséré avant la sélection. La leçon apprise ici est "ne rejetez pas immédiatement les solutions possibles sans y réfléchir". Merci! –

1

Vous devez properly decorate votre fonction CLR pour la marquer comme Accès Déterminique, Précis et Accès aux données/Données système comme DataAccessKind.None.

+0

Hmm je pensais que le marquer déterministe, mais il est pas vraiment ... dans ce cas, il reviendrait la même valeur la plupart du temps, mais certainement pas tout le temps. Je ne suis pas sûr de ce que font les autres ... pouvez-vous élaborer? –

+0

D'où dbo.MyCustomCLRDateFunction fabrique-t-il la date de retour? Avez-vous des tables de recherche? La sortie dépend-elle de l'heure actuelle? Si vous ne pouvez pas marquer la sortie comme déterministe, il y a peu de chances de tromper l'exécution de la requête pour filtrer à distance. –

+0

Eh bien, je pose effectivement cette seule question, mais la réalité est que j'ai environ 10 fonctions différentes qui sont utilisées de différentes manières. Certains dépendent du temps, d'autres non, mais tous ne garantissent TOUJOURS pas la même valeur pour un ensemble d'arguments donné. Ceux qui le sont, je les marquerai certainement comme tels. En outre, DataAccessKind.None n'est-il pas le paramètre par défaut? –

2

Vous pouvez aussi construire une chaîne et d'utiliser un openquery ...

set @sqlString = 
' select into myTable from openquery 
    (remoteServer, 
     "SELECT * FROM Database.dbo.RemoteView WHERE EntryDate > %DTSTART" 
    ) 
' 

set @sqlString = 
    replace(@sqlString, '%DTSTART', 
         (select cast(dbo.MyCustomCLRDateFunction() as char(8)) 
      ) 

EXECUTE sp_executesql @[email protected] 
Questions connexes