Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
Oleg Romantsev
Member

Откуда: Москва
Сообщений: 230
Прошу прощения - что - то не смог найти информацию как сделать сабж...

Нужно для серверных функций ( в частности для оправки мыла - для аттачментов.. ) так как размер может быть большим - передавать содержимое этого поля в переменной - неправильно поэтому решил сохранять во временный файл как это сделать с помощью SQL инструкций?
16 июн 03, 09:55    [230403]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
SerjaTo
Member

Откуда: Барнаул - город орденоносный :)
Сообщений: 52
а если попробовать transformation package создать. правда там кажется существующий файла треба, но может это как-то можно обойти, допустим создать файло один раз а после экспорта с помощью xp_cmdshell его копировать куда-нибудь.
16 июн 03, 10:19    [230431]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
Oleg Romantsev
Member

Откуда: Москва
Сообщений: 230
Нужно типа аналога на MySql
SELECT * INTO OUTFILE 'C:\\tmp\\1.txt' FROM table1;
16 июн 03, 10:43    [230469]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
nandji
Member

Откуда:
Сообщений: 186
правда там кажется существующий файла треба

не треба
16 июн 03, 11:17    [230540]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
BootMaker
Member

Откуда: С-Петербург
Сообщений: 902

set @str='bcp "SELECT au_fname, au_lname FROM pubs..authors ORDER BY au_lname" queryout Authors.txt -c -Sservername -Usa -Ppassword'
exec master..xp_cmdshell @str

Он сам создаст нужный файл.
А вообще почитай про bcp, там все ясно.
16 июн 03, 14:47    [230922]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
Oleg Romantsev
Member

Откуда: Москва
Сообщений: 230
Всё запарился я...
Объясню всё по порядку:
Пишу на delphi dll-ку которая будет отправлять письма по e-mail данные будет брать из таблицы mails где хранятся адреса, заголовки, само сообщение и аттачменты (в подчиненной таблице в бинарных полях)

Всё вроде работает без проблем если не брать во внимание аттачменты
В DELPHI использую компоненты TIdSmtp и TIdMessage
там аттачменты можно прикрутить только через файлы.

Как выйти из этой ситуации подскажите правильный ход а то уж мозгов не хватает.

Заранее благодарен
16 июн 03, 15:42    [231021]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
snake
Member

Откуда: Russia, Penza
Сообщений: 2290
Сам просил!
Значит так:
1. Сохранить файл средтсвами T-SQL можно например как то так https://www.sql.ru/faq/faq_topic.aspx?fid=122
2. Я сделал так, написал расширенную хр. пр. (на основе какого-то найденного проекта в инете). Создаш визардом в VC скелет extended stored procedure. подменишь файл proc.cpp нижеследущим:
#include "stdafx.h"

#include <windows.h>

#define XP_NOERROR 0
#define XP_ERROR 1
#define MAXNAME 25
#define MAXTEXT 256

#ifdef __cplusplus
extern "C" {
#endif

RETCODE __declspec(dllexport) XP_FILE(SRV_PROC *srvproc);
ULONG __declspec(dllexport) __GetXpVersion()
{
return ODS_VERSION;
}

#ifdef __cplusplus
}
#endif

void ShowErrorNusage(LPCTSTR ErrorMessage, SRV_PROC * srvproc){
DBCHAR msgText[MAXTEXT];
if (ErrorMessage == NULL)
ErrorMessage = "Bad Error Message call!";
wsprintf(msgText, ErrorMessage);
//send error message
srv_sendmsg(
srvproc,
SRV_MSG_INFO,
0,
(DBTINYINT)0,
(DBTINYINT)0,
NULL,
0,
0,
msgText,
SRV_NULLTERM
);
//send usage
srv_sendmsg(
srvproc,
SRV_MSG_INFO,
0,
(DBTINYINT)0,
(DBTINYINT)0,
NULL,
0,
0,
"Usage:\n EXEC XP_FILE [file name], [data in] | [data out] OUTPUT",
SRV_NULLTERM
);
}

void SaveFile(LPCTSTR FileName, LPBYTE Contents, DWORD &ContentsLen, DWORD &Error){

HANDLE hFile;
DWORD nBytesWritten = 0;
BOOL bResult;

hFile = CreateFile( FileName, // create FileName
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // no security
CREATE_ALWAYS, // overwrite existing
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template

if (hFile == INVALID_HANDLE_VALUE){
Error = GetLastError();
return ;
}

if (ContentsLen == 0){
Error = 87;
CloseHandle ( hFile );
return ;
}

bResult = WriteFile(hFile, Contents, ContentsLen, &nBytesWritten, NULL);

if (!bResult || nBytesWritten == 0){
Error = GetLastError();
CloseHandle ( hFile );
return ;
}

CloseHandle ( hFile );
Error = 0;
}

void ReadFile(LPCTSTR FileName, LPBYTE &Contents, DWORD &ContentsLen, DWORD &Error){

HANDLE hFile;
DWORD nBytesRead = 0;
BOOL bResult;

hFile = CreateFile(
FileName, // open FileName
GENERIC_READ, // open for reading
FILE_SHARE_READ, // share for reading
NULL, // no security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template

if (hFile == INVALID_HANDLE_VALUE){
Error = GetLastError();
return ;
}

ContentsLen = GetFileSize(hFile, NULL);

if (ContentsLen == INVALID_FILE_SIZE){
Error = GetLastError();
CloseHandle ( hFile );
return ;
}

Contents = new BYTE[ContentsLen];

bResult = ReadFile(hFile, Contents, ContentsLen, &nBytesRead, NULL);

if ( !bResult || nBytesRead == 0 ){
Error = GetLastError();
CloseHandle ( hFile );
return ;
}

CloseHandle ( hFile );
Error = 0;
}

RETCODE __declspec(dllexport) XP_FILE(SRV_PROC *srvproc)
{
DBCHAR spName[MAXNAME];
DBCHAR spText[MAXTEXT];

LPTSTR ErrorMessage = 0;
LPSTR FileName;

LPBYTE DataIn, DataOut;

DWORD Error = 0;
DWORD FileSize;

BYTE bType, bType2;
ULONG cbMaxLen, cbMaxLen2, cbActualLen, cbActualLen2;
BOOL fNull, fNull2;

int iParamCount;

// Name of this procedure
wsprintf(spName, "XP_FILE");
//Send a text message
wsprintf(spText, "%s Extended Stored Procedure", spName);
srv_sendmsg(
srvproc,
SRV_MSG_INFO,
0,
(DBTINYINT)0,
(DBTINYINT)0,
NULL,
0,
0,
spText,
SRV_NULLTERM);

iParamCount = srv_rpcparams(srvproc);

//error if !=2 parameters entered
if (2 != iParamCount){
ShowErrorNusage("Error! Wrong number of parameters.",srvproc);
return (XP_ERROR);
}

//validate parameter io type
if (((srv_paramstatus(srvproc, 1) & SRV_PARAMRETURN)==1)
&&((srv_paramstatus(srvproc, 2) & SRV_PARAMRETURN)==1)
||((srv_paramstatus(srvproc, 1) & SRV_PARAMRETURN)==1)
&&((srv_paramstatus(srvproc, 2) & SRV_PARAMRETURN)==0)){
ShowErrorNusage("Error! Wrong IO definition of parameters.",srvproc);
return (XP_ERROR);
}

//get input parameter 1
if (srv_paraminfo(srvproc, 1, &bType, &cbMaxLen, &cbActualLen, NULL, &fNull) == FAIL){
ShowErrorNusage("Error! Could not read parameter 1.",srvproc);
return (XP_ERROR);
}

if (bType != SRVBIGVARCHAR && bType != SRVBIGCHAR){
ShowErrorNusage("Error! Wrong type of parameter 1.",srvproc);
return (XP_ERROR);
}

if (fNull == 0) {
FileName = new CHAR[cbActualLen+1];
FileName[cbActualLen] = 0;
if (FileName == NULL){
ShowErrorNusage("Error! Null parameter 1.",srvproc);
return (XP_ERROR);
}

if (srv_paraminfo(srvproc, 1, &bType, &cbMaxLen, &cbActualLen, (BYTE *)FileName , &fNull) == FAIL) {
delete FileName;
ShowErrorNusage("Error! Could not read parameter 1's data.",srvproc);
return (XP_ERROR);
}
}
else{
ShowErrorNusage("Error! Failed reading parameter 1.",srvproc);
return (XP_ERROR);
}

//get input parameter 2
if ((srv_paramstatus(srvproc, 2) & SRV_PARAMRETURN)==0){

if (srv_paraminfo(srvproc, 2, &bType2, &cbMaxLen2, &cbActualLen2, NULL, &fNull2) == FAIL){
delete FileName;
ShowErrorNusage("Error! Could not read parameter 2.",srvproc);
return (XP_ERROR);
}

if (bType2 != SRVBIGVARCHAR && bType2 != SRVBIGCHAR && bType2 != SRVIMAGE && bType2 != SRVTEXT && bType2 != SRVNVARCHAR && bType2 != SRVNTEXT){
delete FileName;
ShowErrorNusage("Error! Wrong type of parameter 2.",srvproc);
return (XP_ERROR);
}

if (fNull2 == 0){
DataIn = new BYTE[cbActualLen2+1];
DataIn[cbActualLen2] = 0;
if (DataIn == NULL){
delete FileName;
ShowErrorNusage("Error! Null parameter 2.",srvproc);
return (XP_ERROR);
}
if (srv_paraminfo(srvproc, 2, &bType2, &cbMaxLen2, &cbActualLen2, DataIn , &fNull2) == FAIL){
delete DataIn;
delete FileName;
ShowErrorNusage("Error! Could not read parameter 2'
s data."
,srvproc);
return (XP_ERROR);
}
}
else {
delete FileName;
ShowErrorNusage("Error! Failed reading parameter 2.",srvproc);
return (XP_ERROR);
}
//save
SaveFile(FileName, DataIn, cbActualLen2, Error);
if (Error){
delete DataIn;
delete FileName;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
Error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &ErrorMessage,
0,
NULL );
ShowErrorNusage(ErrorMessage,srvproc);
LocalFree(ErrorMessage);
return (XP_ERROR);
}
else
srv_sendmsg(
srvproc,
SRV_MSG_INFO,
0,
(DBTINYINT)0,
(DBTINYINT)0,
NULL,
0,
0,
"File saved successfuly",
SRV_NULLTERM
);
delete DataIn;
}
else{
//read
ReadFile(FileName, DataOut, FileSize, Error);
if (Error){
delete FileName;
delete DataOut;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
Error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &ErrorMessage,
0,
NULL );
ShowErrorNusage(ErrorMessage,srvproc);
LocalFree(ErrorMessage);
return (XP_ERROR);
}
else
srv_sendmsg(
srvproc,
SRV_MSG_INFO,
0,
(DBTINYINT)0,
(DBTINYINT)0,
NULL,
0,
0,
"File read successfuly",
SRV_NULLTERM);

//return data in output parameter

if(FAIL == srv_paramsetoutput(srvproc, 2, DataOut, FileSize, FALSE)) {
delete FileName;
delete DataOut;
ShowErrorNusage("Error! srv_paramsetoutput return FAIL!\nFAIL is returned when there is no current remote stored procedure, when the parameter is not a return parameter, or when the cbLen argument is invalid...",srvproc);
return (XP_ERROR);
}
delete DataOut;
}
delete FileName;
return XP_NOERROR;
}

варианты использования:
увидишь при неправильном вызове
установка:
=========================================================================
DYNAMIC LINK LIBRARY : XP_FILE
========================================================================


AppWizard has created XP_FILE.dll for you.

This file contains a summary of what you will find in each of the files that
make up your XP_FILE application.

XP_FILE.cpp
This is the main dll source file.

proc.cpp
This file contains the stored procedure XP_FILE

/////////////////////////////////////////////////////////////////////////////
Other standard files:

StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named XP_FILE.pch and a precompiled types file named StdAfx.obj.


/////////////////////////////////////////////////////////////////////////////
Other notes:

After completing this Wizard, copy the XP_FILE.dll over to your SQL Server
\Binn directory.

Add your new Extended Stored Procedure from a Visual Studio Data Project,
or using the SQL Server Enterprise Manager, or by executing the following
SQL command:
sp_addextendedproc 'XP_FILE', 'XP_FILE.DLL'

You may drop the extended stored procedure by using the SQL command:
sp_dropextendedproc 'XP_FILE'

You may release the DLL from the Server (to delete or replace the file), by
using the SQL command:
DBCC XP_FILE(FREE)


/////////////////////////////////////////////////////////////////////////////
на memory leak не тестировал.
в коде
if(FAIL == srv_paramsetoutput(srvproc, 2, DataOut, FileSize, FALSE)) {

delete FileName;
delete DataOut;
ShowErrorNusage("Error! srv_paramsetoutput return FAIL!\nFAIL is returned when there is no current remote stored procedure, when the parameter is not a return parameter, or when the cbLen argument is invalid...",srvproc);
return (XP_ERROR);
}

проблемы - когда выходной параметр имеет тип text, image (FAIL и все собака) не может читать большие файлы в выходные перменные какой-нибудь процедуры.
Если кто просвятит - буду рад неподдельно!
16 июн 03, 15:55    [231053]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
snake
Member

Откуда: Russia, Penza
Сообщений: 2290
никто не пробовал?
18 июн 03, 10:10    [233217]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
snake
Member

Откуда: Russia, Penza
Сообщений: 2290
никто не пробовал?
18 июн 03, 10:10    [233220]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32245
2Oleg Romantsev
Просто считай данные в дельфях, запиши в файл и давай его компонентам. Зачем извращаться с T-SQL?
18 июн 03, 11:51    [233448]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
Oleg Romantsev
Member

Откуда: Москва
Сообщений: 230
alexeyvg : да вот из этой программулина на дельфи и не хотелось бы лезть в базу... для этого ж надо ей задавать логин и пароль а этого делать не хот-ца она должна быть сервисной и работать автономно... и чтоб за ней не приходилось следить... я для этого и решил то написать ее в виде DLL - ки как Extended Stored procedure
19 июн 03, 09:14    [234568]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
Oleg Romantsev
Member

Откуда: Москва
Сообщений: 230
to Snake :

>> проблемы - когда выходной параметр имеет тип text, image
>> (FAIL и все собака) не может читать большие файлы в выходные
>>перменные какой-нибудь процедуры.

Вот в том то и дело что нужна работа с большими файлами... прога должна быть универсальной а не кастрированной ...
19 июн 03, 09:16    [234571]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
snake
Member

Откуда: Russia, Penza
Сообщений: 2290
2Oleg Romantsev,

ТАК ПИСАТЬ ТО ОНА МОЖЕТ БОЛЬШИЕ ФАЙЛЫ!

(это я точно тебе говорю, проверял).
если я правильно понял вот эти слова:
Пишу на delphi dll-ку которая будет отправлять письма по e-mail данные будет брать из таблицы mails где хранятся адреса, заголовки, само сообщение и аттачменты (в подчиненной таблице в бинарных полях) 
)
проблема в том как выгрузить на диск аттачменты (в подчиненной таблице в бинарных полях) так, нет?
Если так, то дай мне час...
19 июн 03, 09:46    [234610]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
Oleg Romantsev
Member

Откуда: Москва
Сообщений: 230
snake именно так !!!
19 июн 03, 09:57    [234625]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
snake
Member

Откуда: Russia, Penza
Сообщений: 2290

/*
--INSTALL
sp_addextendedproc XP_FILE, 'xp_file.dll'
--HELP
sp_helpextendedproc XP_FILE
--UNINSTALL
sp_dropextendedproc XP_FILE
--UNLOAD DLL
DBCC XP_FILE ( FREE )
*/

use tempdb
create table Images (BlobID int IDENTITY primary key, Blob image)
go
insert Images (Blob)
select 'здесь были охрененные куски текста(не стал сюда постить и так хватает :)), не нашел способа красивее вставить более 8k данных
может кто просвятит? опять :)'

go
insert Images (Blob)
select 'тот же текст'
go
select datalength(Blob) from Images
-- данные готовы, "обвернем" "расширенную"

-- в скалярную функцию (чтобы вызвать ее в "select list")


go
create function dbo.WriteFile( @FileName varchar(256), @FileContent image)
returns int
begin
declare @rc int
exec @rc = master..XP_FILE @FileName, @FileContent
/*
если здесь добавить OUTPUT
то "расширенная" должна читать в @FileContent,
иначе писать в файл
*/

return @rc
end
go
select dbo.WriteFile('\\dutch\obmen\'+ltrim(str(BlobID))+'bla.bla',Blob) from Images
go
drop function dbo.WriteFile
go
drop table Images
go

а?
19 июн 03, 10:33    [234679]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
radik
Member

Откуда: Moscow
Сообщений: 190
master..xp_cmdshell 'osql -Uloginname -Ppassword -Q"select * from products" -dNorthwind -oc:\output.txt'
19 июн 03, 10:34    [234680]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
snake
Member

Откуда: Russia, Penza
Сообщений: 2290
radik, не сори здесь пжалста, такое предложение уже было.
19 июн 03, 10:36    [234683]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
radik
Member

Откуда: Moscow
Сообщений: 190
k
19 июн 03, 10:37    [234686]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
snake
Member

Откуда: Russia, Penza
Сообщений: 2290
ок
19 июн 03, 10:39    [234691]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
radik
Member

Откуда: Moscow
Сообщений: 190
мне понравилось предложение (сам на Delphi программлю)

Просто считай данные в дельфях, запиши в файл и давай его компонентам. Зачем извращаться с T-SQL?
19 июн 03, 10:42    [234699]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
Oleg Romantsev
Member

Откуда: Москва
Сообщений: 230
snake:
А этой самомой 'xp_file.dll' у тя нет готовой?
(пишу на дельфях VC не стоит у меня и ставить неохота.. а переводить на DELPHI - долго.. сначало попробовать хочется в работе)
19 июн 03, 10:44    [234705]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
snake
Member

Откуда: Russia, Penza
Сообщений: 2290
держи
http://sura.ru/snake/XP_FILE.dll
19 июн 03, 10:46    [234708]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
Oleg Romantsev
Member

Откуда: Москва
Сообщений: 230
snake:
спасибо, протестирую - отвечу...
19 июн 03, 11:03    [234736]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
Давид_
Member

Откуда:
Сообщений: 5
snake
держи
http://sura.ru/snake/XP_FILE.dll


К сожалению ссылка не работает.
Если можно, выложите еще раз XP_File.dll
Заранее благодарен, Давид.
P.S.
Мой e-mail: zuber@mail.ru
6 мар 06, 23:30    [2423630]     Ответить | Цитировать Сообщить модератору
 Re: Сиквелом сохранить содержимое blob поля в файл на сервере  [new]
K. Alexandr
Member

Откуда:
Сообщений: 209
Не могли бы вы и мне выслать xp_file.dll
на почту kulik_alexandr@mail.ru
спасибо....
4 май 06, 08:37    [2627614]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить