2016-04-14 9 views
3

Kısa bir süre önce tabloya resim eklemek için OPENROWSET kullanmaya başladım. Daha önce, ben her resim (1 resim = 1 INSERT ifadesi) yolunu belirtin ve resmin ikili dize oluşturmak için PHP kullanırsınız: Ancak, ben Tek bir sorgu ile tüm görüntüleri eklemek çalışıyorumTabloda OPENROWSET ile kayıtlı bir yolu nasıl kullanırım?

INSERT INTO nopCommerce..Picture (PictureBinary, MimeType, SeoFilename, AltAttribute, TitleAttribute, IsNew) 
VALUES (
    (
     SELECT * 
     FROM OPENROWSET(BULK '" . $this->image['path'] . "', SINGLE_BLOB) AS Binary 
    ), 
    '" . $this->image['mime_type'] . "', 
    '" . $this->image['seo_filename'] . "', 
    '" . $this->image['alt'] . "', 
    '', 
    0 
) 

. Böylece, her görüntüye giden yolu bir tabloya kaydetmeye başladım ve şimdi her birini daha önce yaptığım gibi eklemem gerekiyor (sadece bir PHP dizgisi yerine tablonun yolunu kullanarak). Ben aşağıdaki girişiminde Fakat:

INSERT INTO nopCommerce..Picture (PictureBinary, MimeType, SeoFilename, AltAttribute, TitleAttribute, IsNew) 
SELECT 
    (
     SELECT * 
     FROM OPENROWSET(BULK 'ImagePath', SINGLE_BLOB) AS Binary 
    ), 
    MimeType, 
    Name, 
    Alt, 
    '', 
    0 
FROM nopRMS..Product_Image_Mappings 
: I (boşuna) sütunun adını tırnak ekleme çalıştı, Yani

Msg 102, Level 15, State 1, Line 5
Incorrect syntax near 'ImagePath'.

:

INSERT INTO nopCommerce..Picture (PictureBinary, MimeType, SeoFilename, AltAttribute, TitleAttribute, IsNew) 
SELECT 
    (
     SELECT * 
     FROM OPENROWSET(BULK ImagePath, SINGLE_BLOB) AS Binary 
    ), 
    MimeType, 
    Name, 
    Alt, 
    '', 
    0 
FROM nopRMS..Product_Image_Mappings 

aşağıdaki hatayı alıyorsunuz

Msg 4860, Level 16, State 1, Line 1
Cannot bulk load. The file "ImagePath" does not exist.

Bunu gerçekleştirmenin bir yolu olmalı, hiçbir yerde çevrimiçi olarak doğru sözdizimini bulamıyorum. SQL Server'a dbo.Product_Image_Mappings.ImagePath yolunu (string) almak için nasıl söyleyeceğini bilen var mı?

GÜNCELLEME sana dbo.Product_Image_Mappings.ImagePath iade edeceğini bir değerin bir örneğini vermeyi unuttum. Bu

GÜNCELLEME Eirikur Eiriksson this thread bir çözüm sunmuştur, ancak bu aynı amaca ulaşılması bir Çok karmaşık bir yönteme benziyor görünür
... ... \\DEREK\WebImages\1\ca-82300.jpg gibi yolları var

GÜNCELLEME (Eirikur Eiriksson adlı Yöntemiyle girişimi)

DECLARE @SQL_STR NVARCHAR(MAX) = N''; 

SELECT @SQL_STR = STUFF(
    (
     SELECT 
      N' 
      UNION ALL 
      SELECT ' 
      + N'(SELECT X.BulkColumn FROM OPENROWSET(BULK ' 
      + NCHAR(39) + im.ImagePath + NCHAR(39) 
      + N', SINGLE_BLOB) AS X) AS PictureBinary,' 
      + NCHAR(39) + im.MimeType + NCHAR(39) 
      + N' AS MimeType,' 
      + NCHAR(39) + im.Name + NCHAR(39) 
      + N' AS SeoFilename,' 
      + NCHAR(39) + REPLACE(im.Alt, '''', '''''') + NCHAR(39) 
      + N' AS AltAttribute,' 
      + N'NULL AS TitleAttribute,' 
      + N'0 AS IsNew' 
     FROM nopRMS..Product_Image_Mappings im 
     FOR XML PATH(''), TYPE 
    ).value('.[1]','NVARCHAR(MAX)'),1,12,N'' 
) 

INSERT INTO nopCommerce..Picture (PictureBinary, MimeType, SeoFilename, AltAttribute, TitleAttribute, IsNew) 
EXEC (@SQL_STR); 

Bu tür çalıştı, ancak yalnızca (7200 + dışına) 42 satır takılı ... Ben t ihtiyacım % 100 doğru olması için :(itiraf etmeliyim, bu sorgu hakkında bir şey değiştirmem gerekebilir, ama bu konuda bir şey bilmiyorum (temel INSERT, SELECT, vb. dışında)

+0

Ayrıca, bu ekleme deyimini bir birleştirme deyiminin içinde kullandığımı belirtmeliyim. Bunun seçeneklerimi de kısıtlayabileceğine inanıyorum (çünkü Dinamik SQL'in tek seçenek olduğunu görüyorum ve "TARGET İLE DEĞİLDİR)" İçinde Dinamik SQL'i çalıştırabileceğime inanmıyorum. – derekmx271

+0

FYI: Biçimlendirmeyi güncelledim Sorguda biraz, ama aynı zamanda SQL Server Central forumunda bu kodu gönderen kişinin adı "SSCertifiable" terimi bir isim değil, siteye kaç nokta ve/veya oturum açma ile ilişkili bir etikettir –

+0

İlk kod örneğinizde PHP kodunuz var, PHP'yi bir PHP sayfasının içinde oluşturup çalıştırıyor musunuz? Bunu bilmek önemlidir. İkinci kod girişimi ('ImagePath' kullanarak) bir imleç kullanılarak elde edilebilir. Her kayıt için tam dinamik dize ve onu yürütür, ancak yavaş olur –

cevap

1

Belki de ' OPENROWSET kullanıyor musunuz? İstediğiniz şey SQLCLR kullanarak çok daha basit ve daha temiz bir şekilde ele alınabilir. Bir dosyanın içeriğini okumak ve bir VARBINARY(MAX) olarak döndürmek için bir Scalar UDF oluşturabilirsiniz. Sonra mevcut sorgunuza uygun olacaktır. Örneğin:

INSERT INTO nopCommerce.dbo.Picture (PictureBinary, MimeType, SeoFilename, 
         AltAttribute, TitleAttribute, IsNew) 
SELECT 
    dbo.GetBinaryFile([ImagePath]) AS [PictureBinary], 
    MimeType, 
    Name, 
    Alt, 
    '', 
    0 
FROM nopRMS.dbo.Product_Image_Mappings; 

Ve dbo.GetBinaryFile() için ne kadar kod alır? İşte burada:

using System; 
using System.Data.SqlTypes; 
using System.IO; 
using Microsoft.SqlServer.Server; 

[return:SqlFacet(MaxSize = -1)] 
[SqlFunction(IsDeterministic = false, IsPrecise = true)] 
public static SqlBytes GetBinaryFile([SqlFacet(MaxSize = 1000)] SqlString FilePath) 
{ 
    if (FilePath.Value.Trim().Equals(String.Empty)) 
    { 
     return SqlBytes.Null; 
    } 

    return new SqlBytes(File.ReadAllBytes(FilePath.Value)); 
} 

Ve T-SQL sarıcı nesne

aşağıdaki ( NULL geçirilen eğer, C# kodu FilePath.IsNull kontrol etmek dolayısıyla gerek yürütme atlar olarak WITH RETURNS NULL ON NULL INPUT hattını dikkat ediniz: -)

CREATE FUNCTION [dbo].[GetBinaryFile](@FilePath NVARCHAR(1000)) 
RETURNS VARBINARY(MAX) 
WITH RETURNS NULL ON NULL INPUT 
AS 
EXTERNAL NAME [CSVParser].[CSVUtils].[GetBinaryFile]; 

Montaj WITH PERMISSION_SET = EXTERNAL_ACCESS olarak işaretlenmesi gerekir.Pek çok kişi, bunu gerçekleştirmek için TRUSTWORTHY veritabanı özelliğini ON'a ayarlamanın kolay yoluna gider, ancak bu bir güvenlik riskidir ve hatta gerekli değildir. Sadece aşağıdakileri yapın ve OFF için TRUSTWORTHY set tutarken EXTERNAL_ACCESS için Meclis ayarlayabilirsiniz:

  1. Oturum Montaj.
  2. Bu DLL'den master'da bir Asimetrik Anahtar oluşturun.
  3. Bu Asymmetric Key'den bir Giriş (master'da) oluşturun.
  4. Yeni Giriş verin EXTERNAL ACCESS ASSEMBLY iznini verin.

Yazdığım aşağıdaki makalede, Visual Studio/SSDT (SQL Server Veri Akışı Araçları) Bu nasıl yapılacağına ilişkin ayrıntılı talimatlar bulabilirsiniz: Stairway to SQLCLR Level 7: Development and Security (Site içeriği görüntülemek için ücretsiz kayıt gerektirir) .

Ayrıca/oluşturarak Meclisi dağıtma ile rahatsız istemiyor herkes için, benzer bir işlev birçok fonksiyonlar vardır ve sürece oluşturulacak olan (SQL# kütüphanenin Tam sürümünde (gerçi için özgür değil) kullanılabilir ücretsiz, File_ * dosya sistemi işlevleri sadece Tam sürümde).

+0

Bu işe yarayabilir :) Bu meclisi kuracağım ve deneyeceğim. Bunun için teşekkür ederim! – derekmx271

İlgili konular