I would like to retreive some binary data from a varbinary(max) column in a SQL Server database for debugging purposes.
What is the easiest way to get this data into a local binary file, preferably without having to write a throw-away console application?
I have tried using SQL Server Management Studio (with the "results to file" option) but this outputs a hex encoded binary string to the file, rather than the raw binary data.
I can't think of any easier way to do this than a throw away bit of C#...
static void Main(string[] args)
{
GetBinaryDataToFile("Server=localhost;Initial Catalog=ReportServer;Integrated Security=true", "D:\\temp.dat");
}
public static void GetBinaryDataToFile(string connectionString, string path)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT Sid FROM Users WHERE UserID = '62066184-8403-494E-A571-438ABF938A4F'";
command.CommandType = CommandType.Text;
using (SqlDataReader dataReader = command.ExecuteReader())
{
if (dataReader.Read())
{
SqlBinary sqlBinary = dataReader.GetSqlBinary(0);
File.WriteAllBytes(path, sqlBinary.Value);
}
dataReader.Close();
}
}
connection.Close();
}
}
This code has been tested using the Users.Sid column (which is of varbinary type) in a default installation of SQL Server wih Reporting Services.
I loved the LinqPad suggestion. I tried it and had a query that spit out the binary to a file within 10 minutes. No VS Project, no build - and now the script is saved and I can pull it up anytime. So cool!
LinqPad script:
var g = from pd in Archives
where pd.ArchiveId == 123
select pd;
var q = from p in printDocs
where p.DocumentId == g.SingleOrDefault().DocumentId
select p;
File.WriteAllBytes("C:\\temp.pdf", q.SingleOrDefault().Pdf.ToArray());
I've found this solution with bcp command (run from command prompt):
c:\temp>bcp "select MYVARBINARYCOL from MYTABLE where id = 1234" queryout "c:\filename.pdf" -S MYSQLSERVER\MYINSTANCE -T
Enter the file storage type of field filedata [varbinary(max)]:
Enter prefix-length of field filedata [8]: 0
Enter length of field filedata [0]:
Enter field terminator [none]:
Do you want to save this format information in a file? [Y/n] n
Starting copy...
1 rows copied.
Network packet size (bytes): 4096
Clock Time (ms.) Total : 15 Average : (66.67 rows per sec.)
I used the -T option to use windows authentication to connect to the DB. If you use password auth, you'll need to use the -U and -P switches to specify a username and password.
But I also like LinqPad suggestion in Robb Sadler's answer and somehow prefer it.
Related
We've deployed nodes and posted a transaction from one node to another using corda and the same got stored in h2 database in "NODE_TRANSACTIONS" table.
TRANSACTION_VALUE column in NODE_TRANSACTIONS table is of BLOB data type.
Please suggest how to extract data from this column in a readable format
We've tried extracting data using resultset.getBinaryStream in java, but not sure of the supported file type in which it needs to be read. Tried with file types image/txt/pdf etc but none of the files were in readable format.
static String url = "jdbc:h2:tcp://localhost:12345/node";
static String username = "sa";
static String password = "";
Class.forName("oracle.h2.Driver");
Connection conn = DriverManager.getConnection(url, username, password);
System.out.println("getting connection: " + conn);
String sql = "SELECT TX_ID, TRANSACTION_VALUE FROM NODE_TRANSACTIONS where rownum<2";
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
InputStream data=rs.getBinaryStream(2);
File file = new File("D:\\blob.txt");
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[1];
while (data.read(buffer) > 0) {
fos.write(buffer);
}
fos.close();
}
conn.close();
Also, please suggest any other way to read the column data using h2 database functions (or) oracle functions
I expect the output to be in a readable format
If you're after having state data stored in a readable format in the database following a transaction, the state must implement the QueryableState interface.
See the docs at https://docs.corda.net/api-persistence.html and the example at https://github.com/corda/cordapp-example/blob/release-V4/java-source/src/main/java/com/example/state/IOUState.java
I have the following code and Insert-statement.. and connection.
SqlConnection con = new SqlConnection();
con.ConnectionString = ("Data Source=DESKTOP-PGHMM6M;Initial Catalog=LocalUsers;Integrated Security=True");
con.Open();
string st = "INSERT INTO data(Username, Password, Hash, EncryptedPassword) VALUES (#Username, #Password, #Hash, #EncryptedPassword)";
SqlCommand cmd = new SqlCommand(st, con);
cmd.Parameters.AddWithValue("#Username", Username);
cmd.Parameters.AddWithValue("#Password", textBox2.Text);
cmd.Parameters.AddWithValue("#Hash", savedPasswordHash);
cmd.Parameters.AddWithValue("#EncryptedPassword", FinalEncryptedPass);
cmd.ExecuteNonQuery(); // invalid object name 'data' < where is this object?
con.Close();
When I run the program it returns the following error:
Invalid object name 'data'
I'm not sure what I did to create this situation. I was fulling around with the "stand-alone sql features" in Visual studio 2017, and I'm not sure where to start, to get back on track to use a local SQL Management Server Studio db that I created.
I found a previous question with the following::
Right click the database project --> Properties
Click Debug
Under Target Connection String, click Edit and select the correct database server
Create a new stored procedure
But I'm not sure what any of this is referring to ^.. any pointers?
welcome to stackoverflow.com
it says you do not have a table (in which you are inserting data) name : "data"...
you must have a database name "LocalUsers". in this database,
create a table name : "data" (with given fields) and you are good to go.
Error:
Either the user, 'myName\user', does not have access to the 'Sample' database, or the database does not exist.
I have the Sample database in SQL Server and also sample cube in the Analysis Server, however I'm getting the error while trying to run the below code which is just for checking the connection.
AdomdConnection conn = new AdomdConnection(#"Data Source=myName\MSSQLSERVER16;Catalog=Sample");
AdomdCommand cmd = new AdomdCommand("SELECT NON EMPTY { [Measures].[Sales Count] } ON COLUMNS FROM [Sample] CELL PROPERTIES VALUE");
AdomdDataReader rdr;
int count = 0;
conn.Open();
rdr = cmd.ExecuteReader();
if (rdr.Read())
{
while (rdr.Read())
{
count++;
}
}
conn.Close();
Console.WriteLine("Count: " + count);
Is there anything wrong in my code? or, it is about the security/access issue. However, I have added the myNmae\user as server administrator at Security of Microsoft Analysis Server. May I get some help please.
I ve solved it, you need to add yourself/user in the Analysis Service thru property > security to get access the db. (also, another mistake was using the db of sql server in connection string instead of Analysis server db). Thanks!
I have looked thoroughly for an answer regarding BCP and extracting a BLOB from my SQL server database. I have followed the various steps found in other threads and I keep coming up with the same file corrupted error.
My database has a column with data type IMAGE in BLOB format. On the users end they can enter photos, pdfs, anything to this field and the server converts them to extremely long BLOBs. My task is to extract these so we can replace them with file name extensions, putting less stress on the database.
My current command is:
bcp "select notes_activex from myDatabase where NCR_NO = '1361'" queryout "C:\BCPtest\testOutput" -S -U -P -f C:\BCPtest\testOutput.fmt
My format file is correct for an image file as per some of the other files posted. I have tried casting the image file first to a varbinary(max) and that still doesnt solve my solution. No matter what I try I can get the BLOB to export but it is a corrupted file.
Added my format file:
11.0
1
1 SQLIMAGE 0 0 "" 1 notes_activex ""
As far as binary data, BCP is intended for extracting data so that it can be later inserted into another SQL Server. It's not saved in a format that's compatible with a binary data file. You'll need to extract the data with a program or script, basically, that's capable of converting the data to bytes.
I've done this in the past with a PowerShell script. I'd use something like the script below. I strongly recommend determining the file from the SQL query if at all possible if you're fetching more than one record at a time.
# Define the connection parameters
$SqlServer = 'MyServerName';
$SqlDatabase = 'MyDatabase';
$SqlConnectionString = 'Data Source={0};Initial Catalog={1};Integrated Security=SSPI' -f $SqlServer, $SqlDatabase;
# Define the query. Note that one field is the file name and the other is the data.
# Modify the WHERE clause to pull the records you need. I am assuming that NCR_NO is not a unique identifier.
$SqlQuery = "select SomeUniqueID AS FileName, notes_activex AS FileData from myDatabase where NCR_NO = '1361'";
# Or use a GUID for the filename
# $SqlQuery = "select NEWID() AS FileName, notes_activex AS FileData from myDatabase";
# Define the path pattern for the output files. {0} will get filled in with the filename.
$OutputFileFullNamePattern = 'C:\Path\To\Output\{0}';
# Create the Connection object and the Command object
$SqlConnection = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $SqlConnectionString;
$SqlCommand = $SqlConnection.CreateCommand();
$SqlCommand.CommandText = $SqlQuery;
# Open the connection
$SqlConnection.Open();
# Create the Sql Data Reader
$SqlDataReader = $SqlCommand.ExecuteReader();
while ($SqlDataReader.Read()) {
# Set in the file name
$OutputFileFullName = $OutputFileFullNamePattern -f $SqlDataReader['FileName'];
# Save the data to the file
[System.IO.File]::WriteAllBytes($OutputFileFullName,$SqlDataReader['FileData']);
}
# Close and dispose of the SQL connection
$SqlConnection.Close();
$SqlConnection.Dispose();
This uses an SqlDataReader, which loads records one at a time. This means your system won't need to load the entire table into memory, but it does mean that you'll have a shared lock on the table until it's done if you're dumping the whole table. If possible, run this query during downtime.
How can I dump some of the tables from my mysql database into an sql file in C#?
Is there a class which does this?
UPDATE: just wanted to mention to DO NOT USE mysqldump, because this application will be installed on many computers and the mysql folder could be on different places.
Dotconnect for mysql might have this feature, but I don't know about the free version.
Otherwise you could just invoke the mysqldump utility and do something like this:
public void DumpMySQLDb(string user, string password, string database, string outputFile) {
var commandLine = string.Format("mysqldump --user={1}--password={2} --hex-blob --databases {3}",
user, password, database)
var process = new Process();
process.StartInfo = new ProcessStartInfo {
FileName = "cmd",
Arguments = string.Format( "/c \"{0}\" > {1}", commandLine, outputFile )
};
process.Start();
}
I built up the sql string table by talbe in the end.