Вопрос

I am currently creating a table and filling it with a binary and a Name:

System.Data.SqlClient.SqlCommand commandAdd = new SqlCommand("CREATE TABLE dbo.tempTable (filename VARCHAR(100), blob VARBINARY(max));", conn);
conn.Open();

if (commandAdd.ExecuteNonQuery() != 0)
{
    byte[] fileBytes = System.IO.File.ReadAllBytes(fileSource);
    System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand("INSERT INTO dbo.tempTable (blob,filename) values (@blob,@name)", conn);
    command.Parameters.AddWithValue("blob", fileBytes);
    command.Parameters.AddWithValue("name", dbName);
}

Then I try to Export it to a Location on the local hdd:

Server server = new Server(new ServerConnection(conn));
server.ConnectionContext.ExecuteNonQuery("xp_cmdshell 'bcp \"SELECT blob FROM " + dbName + ".dbo.tempTable\" queryout " + destinationPath + " -T -c'");

My Problem is that the file from the Export has a wrong size.

Original Size: 2069Kb New Size: 4138Kb

It is always the original size * 2.

Another Problem is that restoring the database to SQL isnt working... I think this is a Problem caused by the first Problem.

sqlConnectionString = "User ID=\"" + username + "\";pwd=\"" + pw + "\";Initial Catalog=master;Data Source=" + dataSource + ";";
using (SqlConnection masterConn = new SqlConnection(sqlConnectionString))
{
    masterConn.Open();
    SqlCommand masterCmd = masterConn.CreateCommand();
    masterCmd.CommandText = "RESTORE DATABASE " + dbName + " FROM DISK = '" + destinationPath + "'";
    masterCmd.ExecuteNonQuery();
}

Thanks in advance, Relax

Это было полезно?

Решение

The Problem was the missing of a Format File. BCP always added a prefix at the beginning of the file. Thats why the file was always corrupted.

Run this in cmd:

bcp [insertYourTableNameHereWithoutBrackets] format nul -S [insertYourServerNameHereWithoutBrackets] -T -n -f C:\Format.fmt

Then run the query in SQL Server:

xp_cmdshell 'BCP "[YourQueryHereWithoutBrackets]" queryout [YourDestinationPathWithoutBrackets] -T -f C:\Format.fmt'

Regards

Другие советы

please find the example of such SP below:

CREATE PROCEDURE [ExportBlobDataFromTable]

@columns varchar(500) = 'ID, BlobColumn, TextColumn', -- the columns used for the export, comma separated
@table varchar(500) = 'BlobTable', -- the table name used for the export
@outputFileName varchar(200) = 'C:\temp\extract.csv', -- fully_qualified_path_to_file
@bcpCommand varchar(1000)
AS
BEGIN

SET @bcpCommand = 'bcp "SELECT ' + @columns + ' FROM ' + @table + '" queryout "' ++@outputFileName + '" -T -n'
EXEC master..xp_cmdshell @bcpCommand
END;

This will create the SP and you can call it from another window like this:

USE [test]
GO

DECLARE @columns varchar(500)
DECLARE @table varchar(500)
DECLARE @outputFileName varchar(200)
DECLARE @bcpCommand varchar(1000)

SET @columns = 'ID, BlobColumn, TextColumn';
SET @table  = 'BlobTable'; 
SET @outputFileName = 'C:\temp\extract.csv';

EXECUTE [dbo].[ExportBlobDataFromTable] 
  @columns
 ,@table
 ,@outputFileName
 ,@bcpCommand
GO

Or from your C# method:

 private void CallSpFromCode()
 {
     var sqlConnectionString = "User ID=\"" + username + "\";pwd=\"" + pw + "\";Initial Catalog=master;Data Source=" + dataSource + ";";
     using (SqlConnection con = new SqlConnection(sqlConnectionString )) {
     using (SqlCommand cmd = new SqlCommand("ExplortBlobDataFromTable", con)) {
      cmd.CommandType = CommandType.StoredProcedure;

      cmd.Parameters.Add("@columns", SqlDbType.VarChar).Value = "ID, BlobColumn,TextColumn";
      cmd.Parameters.Add("@table", SqlDbType.VarChar).Value = "BlobTable";

      con.Open();
      cmd.ExecuteNonQuery();
    }
  }
}

I hope this helps :)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top