Extrait l'image DICOM de RayStation Microsoft SQL Database

On m'a donné une database de secours RayStation, RS_Patients.bak , et j'essaie d'extraire et d'afficher les images DICOM qui y sont stockées. Le problème est double: je ne sais pas lequel des 2 000+ champs (ou combinaisons de champs) se réfère aux images elles-mêmes, et même si je savais où étaient les images, je ne sais pas comment extraire depuis la database vers des files .dcm .

En examinant le schéma, j'ai trouvé quelques champs qui sont de grands champs varbinary (BLOB) et je pense qu'ils pourraient être les champs que je search. FileStream est activé pour la database et il existe un directory FS. J'ai essayé de download ces champs dans des files en utilisant l' utilitaire bcp , mais cela n'a pas généré de DICOM réussis.

Quelqu'un at-il une expérience avec ce type de database / structure d'image? D'autres suggestions pour sortir et visualiser l'image? Pensez-vous que l'image serait composée de quelques champs au lieu d'un seul? Il y a des champs à côté de ce que nous croyons être le champ d'image avec en-têtes pour l'image DICOM: dans la table callefd ImageStack , à côté d'un champ appelé PixelData , il y a des champs PixelSize , SlicePosition , NrPixels , etc.

Aussi, si vous pouvez penser à un autre endroit pour poser cette question, je l'apprécierais aussi.

Modifier la suggestion par @mcNets, la command bcp:

 DECLARE @Command Varchar(400) SET @Command = 'bcp "SELECT TOP 1 PixelData FROM RayStationPatientDB.dbo.ImageStack" queryout "C:\Users\Administrator\Documents\test.dcm" -S WIN-123ABC\MSSQLSERVER01 -T -w' EXEC xp_cmdshell @Command 

De manière générale, vous ne pourrez pas utiliser les résultats de SQL Server pour écrire des données d'image directement. bcp.exe ne va pas non plus vous aider. Vous devez utiliser quelque chose qui comprend que la string binary est des données de file brutes, ou, parce que c'est un FILESTREAM, utilisez quelque chose qui vous donnera le path d'access au file sur le server SQL. J'ai une expérience limitée avec FILESTREAM, mais voici ce que je ferais.

Je ne peux pas répondre définitivement à quel champ utiliser. Cela dépendra de l'application. Si nous supposons que les images DICOM sont stockées dans un FILESTREAM, vous pouvez find les colonnes FILESTREAM disponibles avec ceci:

 select t.name TableName ,c.name ColumnName from sys.tables t join sys.columns c on c.object_id = t.object_id where c.is_filestream = 1 

Si nous supposons également que les images DICOM sont stockées en tant que files image bruts – c'est-à-dire en tant que version binary complète de ce qu'elles seraient si elles étaient enregistrées sur un disque PACS – vous pouvez exécuter ceci pour déterminer le path de chaque file l identité:

 select TableName_Id ,FileData.PathName() from TableName.ColumnName 

Le doc pour la fonction PathName() des colonnes FILESTREAM est ici .

Si vous voulez plutôt tirer datatables via SQL Server dans un sens traditionnel, alors j'utiliserais probablement un script PowerShell pour le faire. Cela a l'avantage de vous permettre d'utiliser des données arbitraires du server pour nommer les files. Cette méthode a également l'avantage de fonctionner sur n'importe quelle colonne binary ou varbinary. En tant qu'inconvénient, cette méthode sera plus lente et utilisera plus d'espace disque, car le server doit lire datatables, les envoyer au client, puis le client écrit datatables sur le disque:

 $SqlQuery = "select Name, FileData from TableName.ColumnName"; $OutputPath = 'C:\OutputPath'; $SqlServer = 'ServerName'; $SqlDatabase = 'DatabaseName'; $SqlConnectionSsortingng = 'Data Source={0};Initial Catalog={1};Integrated Security=SSPI' -f $SqlServer, $SqlDatabase; $SqlCommand = New-Object -TypeName System.Data.SqlClient.SqlCommand; $SqlCommand.CommandText = $SqlQuery; $SqlConnection = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $SqlConnectionSsortingng; $SqlCommand.Connection = $SqlConnection; $SqlConnection.Open(); $SqlDataReader = $SqlCommand.ExecuteReader(); while ($SqlDataReader.Read()) { $OutputFileName = Join-Path -Path $OutputPath -ChildPath "$($SqlDataReader['Name']).dcm" [System.IO.File]::WriteAllBytes($OutputFileName,$SqlDataReader['FileData']); } $SqlConnection.Close(); $SqlConnection.Dispose(); 

Il est également possible d'utiliser les fonctions FILESTREAM pour renvoyer les handles d'API Win32, mais je ne l'ai jamais fait.