Comment charger des files en fonction du shell de command Date de création dans Windows via xp_cmdshell de SQL Server

Dans SQL Server, j'utilise une requête ci-dessous pour charger tous les noms de files ".jpg" d'un directory spécifique (par exemple z 🙂 dans une table.

Je veux savoir s'il existe un moyen de charger les files en fonction de Date de création au lieu de l'invite de command Date de modification dans Windows. La requête ci-dessous ne fonctionne qu'avec Date de modification lors de l'exécution de xp_cmdshell .

 -- Create the table to store file list CREATE TABLE myFilesTable (myFileID INT IDENTITY, myFileName NVARCHAR(256)) -- Insert file list from directory to SQL Server DECLARE @Command varchar(1024) = 'z: & forfiles /m *.jpg /s /d 07/16/2015 /c "cmd /c echo @fdate @ftime @path"' INSERT INTO myFilesTable EXEC MASTER.dbo.xp_cmdshell @Command -- Check the list SELECT * FROM myFilesTable GO 

07/16/2015 dans la variable @Command est la date de modification . Évidemment, la command forfiles n'a pas la forfiles idée de filterr les files par date de forfiles .

Voici quelques résultats de la requête ci-dessus dans laquelle les noms de files sont préfixés par Date de modification .

 myFileID | myFileName ---------------------- 1 | NULL 2 | 8/18/2015 11:13:08 AM "Z:\LDB1 App Export\Top Star_Aluminium Frames & Furniture (B)-31267.jpg" 3 | 8/19/2015 5:44:41 PM "Z:\LDB2 App Export\Soe Tint_Hardware Merchants & Ironmongers-31435.jpg" 4 | 8/19/2015 10:37:13 AM "Z:\Cover App Export\Taw Win Tun_Elecsortingcal Goods Sales & Repairing (A) -31382.jpg" 5 | 8/24/2015 10:34:33 AM "Z:\CP1 App Export\Thiri May_Fabric Shop (B)-30646.jpg" 6 | 8/17/2015 10:08:39 AM "Z:\CP2 App Export\Ko Tin Aung_Building Materials (B)-31300.jpg" 

J'ai aussi essayé d'utiliser la command dir avec timefield /t:c (l'heure de la création) quelque chose comme

 EXEC MASTER.dbo.xp_cmdshell 'dir z: *.jpg /t:c /s' 

Il me donne la date de création mais il me montre le résultat suivant qui n'est pas comme prévu. Je veux les noms de files avec le path complet / noms de directorys comme indiqué dans le résultat précédent.

 myFileID | myFileName ---------------------- 1 | Volume in drive Z is Publication 2 | Volume Serial Number is 3EF0-5CE4 3 | NULL 4 | Directory of Z:\ 5 | NULL 6 | 07/28/2015 06:41 PM <DIR> . 7 | 07/28/2015 07:06 PM <DIR> .. 8 | 03/05/2015 11:42 AM <DIR> LDB1 App Export 9 | 03/05/2015 05:31 PM <DIR> LDB2 App Export 10 | 0 File(s) 0 bytes 11 | NULL 12 | Directory of Z:\LDB1 App Export 13 | NULL 14 | 03/05/2015 11:42 AM <DIR> . 15 | 07/28/2015 06:41 PM <DIR> .. 16 | 07/28/2015 06:49 PM 2,981,526 Kyaw Phay_Dental Equipment (A)-30998.jpg 17 | 08/31/2015 03:10 PM 3,126,629 Venus_Fashion Shops-31438.jpg 18 | 07/28/2015 06:49 PM 3,544,247 Marvellous_Tourism Services-30986.jpg ... | ... 

Le résultat attendu devrait être quelque chose comme ci-dessous,

 myFileID | CreatedDate | myFileName ---------------------------------------------- 1 | 8/10/2015 11:24:16 AM | "Z:\LDB1 App Export\Top Star_Aluminium Frames & Furniture (B)-31267.jpg" 2 | 8/10/2015 11:24:27 AM | "Z:\LDB2 App Export\Soe Tint_Hardware Merchants & Ironmongers-31435.jpg" 3 | 8/12/2015 10:05:22 AM | "Z:\Cover App Export\Taw Win Tun_Elecsortingcal Goods Sales & Repairing (A) -31382.jpg" 4 | 8/12/2015 10:05:22 AM | "Z:\CP1 App Export\Thiri May_Fabric Shop (B)-30646.jpg" 5 | 8/12/2015 10:05:22 AM | "Z:\CP2 App Export\Ko Tin Aung_Building Materials (B)-31300.jpg" 

Toute aide serait très appréciée 🙂

Voici une façon d'parsingr la sortie de la command DIR:

 --Create the table to store file list CREATE TABLE myFilesTable (myFileID INT IDENTITY, myFileCreateDate datetime, myFileName NVARCHAR(256)) --Create temporary table to store output of DIR command CREATE TABLE #DirectoryOutput (LineID INT IDENTITY, LineData NVARCHAR(256)) --Insert file list from directory to SQL Server DECLARE @Command varchar(1024) = 'dir z: *.jpg /t:c /s' INSERT INTO #DirectoryOutput EXEC MASTER.dbo.xp_cmdshell @Command --Check the list insert into myFilesTable select convert(Datetime,(left(LineData, 20))) CreateDate, FilePath2.FilePath + '\' + right(LineData,len(LineData)-39) Filename from #DirectoryOutput cross apply ( select Max(LineID) LineID from #DirectoryOutput FilePaths where LEFT(LineData,14)=' Directory of ' and FilePaths.LineID < #DirectoryOutput.LineID ) FilePath1 join ( select LineID, RIGHT(LineData, LEN(LineData)-14) FilePath from #DirectoryOutput FilePaths where LEFT(LineData,14)=' Directory of ' ) FilePath2 on FilePath1.LineID = FilePath2.LineID where ISDATE(left(LineData, 20))=1 order by 1 select * from myFilesTable GO 

J'ai légèrement changé votre table pour inclure une colonne séparée pour la date de création:

 CREATE TABLE myFilesTable ( myFileID int IDENTITY , myFileName nvarchar(256) , myFileCreationDate datetime ) 

Vous pouvez utiliser le script PowerShell suivant pour get les informations de directory et l'écrire dans la table SQL:

 Import-Module "C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\SQLPS" -DisableNameChecking $files = Get-ChildItem "z:\" -Filter "*.jpg" -recurse | Where-Object { $_.CreationTime -ge "07/16/2015" } | Select-Object FullName, CreationTime foreach ($file in $files) { $creationTime = $file.CreationTime -f "dd-MM-yyyy hh:mm:ss" $file.FullName = $file.FullName -replace "'", "''" Invoke-Sqlcmd -ServerInstance "YourInstance" ` -Database "YourDatabase" ` -Query ("INSERT INTO {0} (myFileName, myFileCreationDate) VALUES ('{1}', '{2}')" ` -f "myFilesTable", $file.FullName, $creationTime) } 

Remplacez la valeur YourInstance avec votre nom d'instance et la valeur YourDatabase avec le nom de votre database.

Je déconseille fortement d'utiliser xp_cmdshell car il ouvre un shell de command Windows avec le même context de security que le count de service du server SQL. C'est un risque de security et il est préférable de désactiver la command xp_cmdshell.

Vous pouvez mieux exécuter la command PowerShell sur le server SQL. La condition préalable est que le module SQLPS soit disponible (pour le commandlet Invoke-SqlCmd). Cette condition préalable est remplie lorsque vous avez installé SQL Server.

MODIFIER:

Donc, si vous voulez vraiment le faire via xp_cmdshell, vous pouvez save le script PowerShell sur votre server SQL Server et l'exécuter de la manière suivante (j'ai modifié le path d'access au file SQLPS dans le script PowerShell, en supposant que SQL Server 2012):

 EXEC xp_cmdshell 'powershell.exe -file "C:\FileList.ps1" -ExecutionPolicy Unressortingcted' 

Où C: \ FileList.ps1 est votre script PowerShell enregistré.

forfiles n'offre que le filter de date modifié ( voir docs ). Au lieu de cela, vous pouvez exécuter PowerShell à partir de SQL (par exemple, comme ceci ) et comme PowerShell a beaucoup de bons filters, il sera facile de le faire en fonction de la date de création (par exemple, comme ceci ).

Si vous modifiez votre @Command à

 DECLARE @Command varchar(1024) = '@echo off For /f "tokens=1-6 delims= " %%a in (''dir *.png /t:c /o:d'') do ( if exist %%e ( echo %%a %CD%%%e ))' 

Le @echo off s'assure que les commands ne sont pas affichées et cette ligne doit être sur une ligne séparée. J'ai échappé les guillemets simples dans SQL en remplaçant 'avec' (2 guillemets simples pas une double citation).

La command dos produit la sortie suivante:

 Date FileNameWithPath 07/15/2015 [Drive]:\[Path]\image.jpg 

J'espère que cela vous aidera à vous rapprocher de ce dont vous avez besoin.