2015-08-30 20 views
6

In SQL Server, sto utilizzando una query di seguito per caricare tutti i nomi di file ".jpg" da una directory specifica (ad esempio z :) in una tabella .Come caricare i file in base a Data di creazione nella shell dei comandi di Windows tramite xp_cmdshell di SQL Server

Voglio sapere se c'è un modo per caricare i file in base al Creato Data invece di Modified Data nel prompt dei comandi di Windows. La query di seguito funziona solo con Data di modifica quando si esegue 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 nella variabile @Command è la data Modified. Ovviamente il comando forfiles non ha la minima idea di filtrare i file per Data di creazione.

Di seguito sono riportati alcuni risultati della query sopra riportata in cui NomeFile sono prefissati da Data di modifica.

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_Electrical 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" 

ho anche provato ad utilizzare dir comando con timeField /t:c (l'ora di creazione) qualcosa come

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

Mi dà la data Creato ma mi mostra il seguente risultato che non è così previsto. Voglio i nomi dei file con nomi di percorso/directory completi come mostrato nel risultato precedente.

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 
...  | ... 

Il risultato atteso dovrebbe essere qualcosa come qui di seguito,

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_Electrical 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" 

Qualsiasi aiuto sarebbe molto apprezzato :)

+0

Grazie @marc_s per la modifica :) purtroppo nessuno sta rispondendo alla mia domanda: \ – kolunar

+1

puoi aggiungere il tag 'batch-file' che sembra essere più popolare.Invece dei forfiles puoi provare con WMIC che offre più controllo, ma mi ci vorrà del tempo per creare una query, – npocmaka

+0

Rif .: utilizzando il comando dir http://superuser.com/questions/355771/windows-listing-of-files-from-command-line – kolunar

risposta

5

Ecco un modo è possibile analizzare l'output del comando 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 
+0

Grazie, la tua risposta è molto vicina a quello che mi aspetto :) – kolunar

2

forfiles offre solo il filtro data di modifica (see docs). Invece è possibile eseguire PowerShell da SQL (ad esempio like this) e poiché PowerShell dispone di numerosi filtri piacevoli, sarà facile farlo in base alla data di creazione (ad esempio like this).

4

ho un po 'cambiato il vostro tavolo per includere una colonna separata per la data di creazione:

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

È possibile utilizzare seguente script PowerShell per ottenere le informazioni della directory e scriverlo nella tabella 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) 
} 

Sostituire il valore YourInstance con il nome dell'istanza e il valore YourDatabase con il nome del proprio database.

Mi sconsiglio vivamente di utilizzare xp_cmdshell quando apre una shell di comandi Windows con lo stesso contesto di sicurezza dell'account del servizio SQL server. Questo è un rischio per la sicurezza ed è meglio disabilitare il comando xp_cmdshell.

È possibile eseguire al meglio il comando PowerShell su SQL Server. Il prerequisito è che il modulo SQLPS sia disponibile (per il comando Invoke-SqlCmd). Questo prerequisito viene soddisfatto quando si installa SQL Server.

EDIT:

Quindi, se si vuole veramente farlo tramite xp_cmdshell, è possibile salvare lo script PowerShell in SQL Server ed eseguirlo nel modo seguente (ho modificato il percorso del file SQLPS nella lo script PowerShell, a patto di avere SQL Server 2012):

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

Dove C: \ FileList.ps1 è lo script PowerShell salvato.

+1

Se davvero hai bisogno di xp_cmdshell, per favore fammi sapere allora Proverò a lavorare su qualcosa. –

+0

Grazie signore, apprezzo molto la risposta. Proverò il tuo snippet anche se devo accettare un'altra risposta dal momento che la domanda che viene posta domanda favorisce l'uso di xp_cmdshell con il prompt di windows cmd che non può più essere modificato per essere abbastanza giusto per la taglia. – kolunar

+1

Modificato la mia risposta in modo che funzioni tramite xp_cmdshell. –

1

Se si cambia il Comando @ per

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))' 

Il @echo off assicura che i comandi non vengono visualizzati e questa linea deve essere su una riga separata. Sono sfuggito alle virgolette singole in SQL sostituendo 'con' '(2 virgolette singole non virgolette doppie).

il comando DOS produce il seguente output:

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

Spero che questo ti aiuta a ottenere più vicino a quello che ti serve.

+0

Ho provato il comando nel prompt dei comandi come 'Y: \> For/f" token = 1-6 delim = "%% a in ('dir * .png/t: c/o: d') do (se esiste %% e (echo %% a% CD %%% e)) 'quindi mostra' %% a era inatteso in questo momento' – kolunar

+0

Ricorda che questa è la programmazione di file batch. Inserire il codice all'interno di un file batch, cioè DirPicList.bat e funzionerà. –

+0

Digitare quanto segue al prompt dei comandi per creare il file DirPicList.bat: copia con DirPicList.bat [Invio] @echo off [Invio] Per/f "token = 1-6 delim =" %% a in ('dir *.png/t: c/o: d ') do (se esiste %% e (echo %% a% CD %%% e)) [Invio] [Premere Ctrl-Z] [Invio] Modifica: include crea file batch dal prompt dei comandi. –