Comment puis-je faire en sorte que SSMS utilise le chemin relatif du script actuel avec: r en mode sqlcmd comme le fait SSDT?

11

Si j'ai foo.sql et bar.sql dans le même dossier, foo.sql peut référencer bar.sql lorsqu'il est exécuté à partir de SSDT en mode sqlcmd avec :r ".\bar.sql". Cependant, SSMS ne le trouvera pas. Procmon montre que SSMS recherche %systemroot%\syswow64:

Capture d'écran de Procmon annoté

Comment dire à SSMS de rechercher dans le dossier dans lequel le script actuel est enregistré sans déclarer explicitement le chemin?

Justin Dearing
la source

Réponses:

8

Obtenir un chemin relatif dans SSMS n'est pas si simple car vous n'exécutez pas le script; SSMS a chargé le script en mémoire et exécute son texte. Le répertoire / dossier actuel est donc le dossier de démarrage du processus par défaut. Vous pouvez le voir en exécutant ce qui suit en mode SQLCMD dans SSMS:

!! PWD

Cependant, j'ai trouvé un moyen de faire ça un peu. J'admets que ce n'est pas la façon la plus idéale de le faire, cependant, il semble actuellement être le seul moyen d'obtenir un vrai chemin relatif (étant donné que définir le chemin dans une variable n'est pas vraiment "relatif" en soi ).

Vous pouvez donc:

  1. Exécutez une commande DOS pour trouver foo.sql et stockez le chemin d'accès à ce fichier dans un fichier texte dans un dossier que vous pouvez obtenir à partir de SSMS, soit parce qu'il s'agit d'un chemin codé en dur, soit parce qu'il utilise une variable d'environnement disponible pour à la fois la commande DOS et le mode SQLCMD dans SSMS
  2. Lorsque vous stockez le chemin dans ce fichier, stockez-le en tant que commande de mode SQLCMD qui définit une variable sur ce chemin
  3. Importez ce fichier texte dans SSMS en utilisant :ret il définira cette variable sur le chemin souhaité
!! CD C:\ & FOR /F %B IN ('DIR /B /A -HS /S foo.sql') DO ECHO :setvar mypath "%~dpB" > %TEMP%\relative_path.txt

:r $(TEMP)\relative_path.txt

:r $(mypath)\bar.sql

Remarques:

  • La méthode ci-dessus suppose qu'un seul fichier sur le système est nommé foo.sql . Si plusieurs fichiers portent ce nom, le dernier trouvé sera le chemin défini dans le fichier relative_path.txt

  • Faire le CD C:\démarre à la racine du lecteur C : . Ce n'est probablement pas l'endroit le plus efficace pour commencer. Si vous avez généralement vos fichiers SQL dans une zone telle que C: \ Users {YourLogin} \ Documents \ Visual Studio 2013 \ Projects , modifiez simplement la CDcommande pour vous rapprocher de la destination, telle que:

    !! CD C:\Users\{YourLogin}\Documents\Visual Studio 2013 & FOR ...
Solomon Rutzky
la source
C'est créatif, mais trop lent et gourmand en disque.
Justin Dearing
2
@JustinDearing Comme je l'ai dit dans ma réponse, c'est a) non idéal, et b) lent si on démarre à partir d'un répertoire racine, mais c) la seule façon que je peux voir de le faire est techniquement relative. Je ne sais pas si l'indexation du disque dur supprimerait le problème de performances.
Solomon Rutzky
Bien que cela me rend triste, c'est définitivement la meilleure réponse qui n'implique pas de définir le chemin à partir d'un autre script de commande ou de le coder en dur dans le fichier.
QueueHammer
5

Je peux me tromper, mais je ne pense pas que ce soit possible. Veuillez consulter ces liens pour un exemple de ce que d'autres ont fait (aucun n'est idéal).

/programming/8753541/how-to-get-the-relative-path-of-file-in-sqlcmd-mode-in-ssms

http://boardreader.com/thread/Specifying_relative_path_to_r_command_in_lmlz__f0c78408-e001-48a2-8369-338c9534f496.html

Marteau SQL
la source
Eh bien, ça craint, mais je suppose que cela encourage l'utilisation du SSDT.
Justin Dearing
2

Je recommande d'enregistrer votre fichier de variables sqlcmd dans 'C: \ Users \ your_nt_login_name \ AppData \ Local \ Temp' et de le référencer de tous mes projets en tant que $ (TEMP) \ sqlcmd_variables.sql.

Vernon Jimmerson
la source