ورود

View Full Version : کپی یک فایل در سرور با استفاده از IP با اسکیوال سرور



khorsandreza
پنج شنبه 14 شهریور 1392, 23:01 عصر
سلام
من تاپیکی را در اینجا (http://barnamenevis.org/showthread.php?417795-%DA%A9%D9%BE%DB%8C-%DB%8C%DA%A9-%D9%81%D8%A7%DB%8C%D9%84-%D8%AF%D8%B1-%D8%B3%D8%B1%D9%88%D8%B1-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-IP)ایجاد کردم تا با استفاده دستورات دلفی فایلی را از کلاینت در سرور کپی کنم دوستان راهنمائی کردند که حال از اسکیول 2008 برای پایگاه داده استفاده می کنید کپی و حذف فایل در سرور را با استفاده از اسکیو سرور انجام بدم
حال کل سناریو:
تعداد زیادی فایل صوتی و تصویری دارم میخواهم کاربر با انتخاب یک فایل بر روی رایانه خود بر روی سرور کپی بشه با این شرط که نمیخواهم پوشه و یا درایو سمت سرور به اشتراک گذاشته شود و یا MapDrive ساخته شود

ضمننا در دستور زیر مسیر سرور چگونه تعریف شده

EXEC xp_cmdshell 'copy C:\Temp\Tuesday_08042009.xml \\MyServerIp\Data\Downloads'

Reza_Yarahmadi
شنبه 16 شهریور 1392, 17:05 عصر
ابتدا دستور زیر رو یکبار روی SQL Server اجرا کنید

EXEC sp_configure 'Ole Automation Procedures', 1
RECONFIGURE
بعد فایل رو بصورت باینری به سرور بفرستید و با استفاده از دستورات زیر اونو توی محل دلخواه روی سرور ذخیره کنید.
DECLARE @ObjectToken INT
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @BinaryFileData
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @FilePath, 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken

khorsandreza
یک شنبه 17 شهریور 1392, 20:25 عصر
[QUOTE=Reza_Yarahmadi;1869952]ابتدا دستور زیر رو یکبار روی SQL Server اجرا کنید

بعد فایل رو بصورت باینری به سرور بفرستید و با استفاده از دستورات زیر اونو توی محل دلخواه روی سرور ذخیره کنید.
DECLARE @ObjectToken INT
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @BinaryFileData
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @FilePath, 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken[/QUOTE
سلام
با تشکر از عنایتی که داشتین من قسمت اول را پیدا کرده بودم ولی از قسمت دو دقیقا سر در نیاورد اگه ر قالب یک sp که نام فایل مبدا و مقصد را ریافت و فایل را بر روی سروی که اسکیوال نصب شده در یک مسیر خاص (e:\mvf\ ) کپی کنه
با مثال شما کلی کنجار رفتم ولی نتونستم

khorsandreza
یک شنبه 17 شهریور 1392, 21:15 عصر
آقای یار محمدی مجددا سلام
من با استفاده از روش زیر میتونم یک فایلی را در کامپیوتر لوکال از یک مبدا به یک مقصد کپی بکنم حال اگر اسکیو سرور بر روی یک سرور با IP مثلا (192.168.1.1 ) نصب شده باشه و بخواهیم فایل را از روی لوکال بر روی سرور بفرستیم چگونه آدرس دهی می کنیم

ALTER PROCEDURE [dbo].[CopyFile]
AS
BEGIN

DECLARE @File VARCHAR(max)
DECLARE @CopyString VARCHAR(max)
SET @File = 'f:\mvf\1.jpg'

SET @CopyString ='copy f:\Images\1.jpg'+ ' "'+ @File + '"' ;
print @CopyString;
EXEC xp_cmdshell @CopyString

END
-- exec CopyFile


با این فرض که در کامپیوتر سرور در مسیر E:\MVF کپی بشه

Reza_Yarahmadi
دوشنبه 18 شهریور 1392, 12:12 عصر
IP سرور مهم نیست ، این دستور روی سرور قراره انجام بشه ، در واقع سرور باید به فایل روی کلاینت دسترسی پیدا کنه.
یک Share Folder روی کلاینت درست کنید و دسترسی به Everyone بدید و دستوری شبیه دستور زیر استفاده کنید
Declare @SourceFilePath varchar(max)

Set @SourceFilePath = '\\ClientIPOrComputerName\SharedFolder\...\FileNam e.txt'

EXEC xp_CmdShell 'Copy ' + @SourceFilePath + 'E:\MVF\FileName.txt'

اون نمونه کدی که گذاشتم ، از سمت کلاینت باید اطلاعات فایل بصورت باینری ارسال بشه (BinaryFileData@) و سمت سرور و توسط SQL Server روی سیستم (FilePath@) ذخیره بشه. توی این حالت دیگه نیازی نیست به ازا هر کلاینت یک ShareFolder درست کنید و فایل مورد نظر کاربر رو توی اون کپی کنید و ... هر فایلی که کاربر انتخاب میکنه توسط برنامه خونده میشه ، محتویاتش بصورت ارایه ای از Byte به سرور ارسال میشه و اونجا توی پوشه ای که تعیین کردید ذخیره میشه.

khorsandreza
دوشنبه 18 شهریور 1392, 17:14 عصر
اون نمونه کدی که گذاشتم ، از سمت کلاینت باید اطلاعات فایل بصورت باینری ارسال بشه (BinaryFileData@) و سمت سرور و توسط SQL Server روی سیستم (FilePath@) ذخیره بشه. توی این حالت دیگه نیازی نیست به ازا هر کلاینت یک ShareFolder درست کنید و فایل مورد نظر کاربر رو توی اون کپی کنید و ... هر فایلی که کاربر انتخاب میکنه توسط برنامه خونده میشه ، محتویاتش بصورت ارایه ای از Byte به سرور ارسال میشه و اونجا توی پوشه ای که تعیین کردید ذخیره میشه.

با عرض پوزش مینوننین یک مثال ساده بفرمائین متوجه نمی شم فایل را چگون بصورت باینری با اس کیو سرور باید ارسال کرد .بی نهایت سپاسگذارم

Reza_Yarahmadi
دوشنبه 18 شهریور 1392, 17:30 عصر
من با دلفی آشنا نیستم
شبه کد #C زیر رو تغییر بدید و ...
سمت سرور یه SP بصورت زیر بنویسید
Create Proc SaveFile
@FileData varbinary(max),
@FileName nvarchar(100)
AS
Begin
Declare @FilePath nvarchar(150)
Set @FilePath = 'Directory Path in Server' + @FileName

Declare @ObjectToken INT
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @FileData
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @FilePath, 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken
End
از سمت برنامه کلاینت هم دستوری شبیه شبه کد زیر بنویسید
SqlCommand cmd = new SqlCommand("SaveFile", connection);
cmd.Parameters.Add("@FileData", File.ReadAllByte("File Path in Client"));
cmd.Parameters.Add("@FileName", "File Name in Client");
connection.Open();
cmd.Execute();
connection.Close();

khorsandreza
پنج شنبه 21 شهریور 1392, 00:57 صبح
سلام من با استفاده از پست قبلی فایلی را برای ذخیره در سرور با استفاده از اس کیو سرور انجام میدم ولی خطائی را به شکل زیر نمایش میده باید تنیمات خاصی روی اس کیو سرور انجام بدم؟

khorsandreza
پنج شنبه 21 شهریور 1392, 12:27 عصر
سلام ارسال فایل به سمت سرور به این صورت درست شد فقط یک اشکال فایل های بزرگتر از 25 مگابایت را رار سال نمی کنه هرچند که مینویسه ارسال شد و خطائی نمیده ولی سمت سرور چیزی کپی نمی شه برای فایل های بزرگتر تدبیر خاصی باید در نظر گرفت


SqlCommand cmd = new SqlCommand("SaveFile", connection);
cmd.Parameters.Add("@FileData", File.ReadAllByte("File Path in Client"));
cmd.Parameters.Add("@FileName", "File Name in Client");
connection.Open();
cmd.Execute();
connection.Close();

Reza_Yarahmadi
شنبه 23 شهریور 1392, 13:32 عصر
مشکل شما به این دستورات مربوط نمیشه. نوع (varbinary(max تا 32^2 بایت رو پشتیبانی میکنه.
مشکل از دستورات لود فایل (سمت برنامه) است.
(این کد رو برای فایلی با حجم 230MB تست گرفتم مشکلی نداشت.)

khorsandreza
شنبه 23 شهریور 1392, 22:26 عصر
مشکل شما به این دستورات مربوط نمیشه. نوع (varbinary(max تا 32^2 بایت رو پشتیبانی میکنه.
مشکل از دستورات لود فایل (سمت برنامه) است.
(این کد رو برای فایلی با حجم 230MB تست گرفتم مشکلی نداشت.)

سلام آقای یار محمدی با پوزش سوال در مورد کدهای Sql Sever بود کلا از سایز 25 مگا بع بعد ارسال نمیشه حتی با دستورات C#‎ هم امتحان کردم نشد

Create Proc SaveFile
@FileData varbinary(max),
@FileName nvarchar(100)
AS
Begin
Declare @FilePath nvarchar(150)
Set @FilePath = 'Directory Path in Server' + @FileName

Declare @ObjectToken INT
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @FileData
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @FilePath, 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken
End

khorsandreza
چهارشنبه 03 مهر 1392, 10:09 صبح
ابتدا دستور زیر رو یکبار روی SQL Server اجرا کنید

بعد فایل رو بصورت باینری به سرور بفرستید و با استفاده از دستورات زیر اونو توی محل دلخواه روی سرور ذخیره کنید.
DECLARE @ObjectToken INT
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @BinaryFileData
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @FilePath, 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken

سلام
من با استفاده از کدهای بالا بروش FileStreim فایلی را از کلاینت به سرور انتقال میدهم با انکه خو SqlServer حجم فایل ارسالی از این روش را تا 2GB ذکر کرده ولی عملا بیشتر از 100MB انتقال داده نمیشه میخواستم بدان اگر بخواهیم یک فایل یزرگ (800MB) بصورت بلوکی و تکه تکه شده به سمت اسکیوال بفرستیم و درنهایت تما بلوکها را به اتصال بدیم امکانپذیر است فکر می کنم با این شیوه هم سرعت کپی کردن بالا میره و هم فایل های با حجم بزرگتر نیز کپی میشه

Reza_Yarahmadi
چهارشنبه 03 مهر 1392, 12:50 عصر
محمدودیت موجود احتمالا بدلیل ایجاد محدودیت سیستم عامل بر روی برنامه شماست (برای امتحان روی یک سیستم با رم بالای 8 گیگ تست کنید)
FileStream (و بالطبع FileTable )از قابلیت Partial Insert پشتیبانی نمیکنه.
یه راه حل (یک مقدار غیر منطقی) اینه که یک جدول با یک فیلد (VarBinary(max ایجاد کنید و فایل رو ابتدا بصورت Partial توی این فیلد ذخیره کنید و پش از اتمام ثبت ، اون فیلد رو روی سیستم ذخیره کنید.