I have a c# application that is conected to a access database, I am then using a openfiledialog to find a image and then display details about this, I then want to save this to the database. But when i try to do this i get a error saying its too big. So what is the way around this? I want the file path saved and then be able to view it later in my main window.
private void button2_Click(object sender, EventArgs e)
{
DataRow drNewRow = m_dtMedia.NewRow();
drNewRow["File_Path"] = textBox1.Text;
drNewRow["Subject"] = textBox2.Text;
drNewRow["Title"] = textBox3.Text;
drNewRow["Keyword_Search"] = textBox4.Text;
drNewRow["MediaType"] = textBox5.Text;
m_dtMedia.Rows.Add(drNewRow);
m_daDataAdapter.Update(m_dtMedia);
m_rowPosition = m_dtMedia.Rows.Count - 1;
this.ShowCurrentRecord();
this.Close();
this works as i have tried typing in just letters and it will save and update the database, saving images on the other hand doesnt.
The error message
OLeDb exception was upheld
The field is too small to accept the amount of data you attempted to add. Try inserting or pasting less data.
Uploading and Downloading BLOBs to Microsoft Access This will explain you how to store image in Access database.
Microsoft Access stores BLOB data in the a field with an OLE Object
data type. If you are
creating the table from a SQL statement, the data type is IMAGE
(similar to SQL Server).
For example
CREATE TABLE File (
FileName VARCHAR(255),
Size INT,
Type VARCHAR(255),
DateUploaded DATETIME,
File IMAGE,
CONSTRAINT File_PK PRIMARY KEY(FileName)
)
Related
Actually I have some data loaded from a access db file in datagridview (in my winform application) and after making changes on dataset I want to save it in a new table of a new access db file through save file dialogue.
I've searched about this but in most of articles they usually tell about updating the dataset in the same access file from which the data has been loaded.but I want the application to create a new access db file with updated data in it. is it possible to do so?
and yup I'm using Oledb technology for accessing data.
thank you
Make a copy from exist db (File.copy), change the connection string and save the changes in this new database.
public string _strCnn = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\myFolder\dataBase.accdb;";
public void SaveChanges()
{
System.IO.File.Copy(#"C:\myFolder\dataBase.accdb;", #"C:\myFolder\NEWdataBase.accdb;");
_strCnn = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\myFolder\NEWdataBase.accdb;";
//TODO: Save changes
}
I am trying to figure out how to allow my users to be able to save their outlook files to a sql database using c#/.net. I am using a normal file upload control and what I thought was I could just save it is a string but and put in a link button but that didn't work for me.
This was my idea for the code:
string ImageName1 = string.Empty;
byte[] Image1 = null;
if (Images1.PostedFile != null && Images1.PostedFile.FileName != "")
{
ImageName1 = Path.GetFileName(Images1.FileName);
Image1 = new byte[Images1.PostedFile.ContentLength];
HttpPostedFile UploadedImage = Images1.PostedFile;
Images1.PostedFile.InputStream.Read(Image1, 0, Images1.PostedFile.ContentLength);
UploadedImage.InputStream.Read(Image1, 0, (int)Images1.PostedFile.ContentLength);
}
Any information on how to do that would be helpful!
You can store files as BLOBs in the database.
I don't quite follow your code, normally you call a stored procedure and pass parameters or specify the command as text in c# for communicating with the SQL server.
This link gives an example of how to insert blob into database.
I am making a program which requires getting the local directory of an image from a MySQL database table. For the moment, I have made the directory of the image I want to retrieve equal to C:\Users\User\Pictures\PictureName.PNG in the MySQL table. The method I have written up is able to retrieve this data from the database through a Select statement and set the PictureBox image as a new Bitmap with the path retrieved from the Selectstatement.
I couldn't find the information I was looking for online as most of the answers relate to using the BLOB field in MySQL to store images, but my question is if I were to put my database on a server and with the pictures on there too, would my method scale to accommodate for those changes or would I have to add other functionality in order for it to work on a server as well?
Here is my code below:
public void setImage() {
string path = sql.RetrieveImage(SelectQuery.RetrievePicture());
PictureBox1.Image = new Bitmap(path);
}
public string RetrieveImage(Query query) {
string path = "";
// OpenDatabaseConnection() will open up a connection to the database
// through connection and if successful, will return true.
if (this.OpenDatabaseConnection()) {
// query.ToSql() returns a string format of the select statement
// required to retrieve the local image directory
using (MySqlCommand cmd = new MySqlCommand(query.ToSql(), connection)) {
MySqlDataReader dataReader = cmd.ExecuteReader();
dataReader.Read();
path = dataReader[0] + "";
dataReader.Close();
}
this.CloseDatabaseConnection();
}
return path;
}
Storing images in a DB is a bad idea. Storing paths to image files is a much better way to go, IMO.
This SO question has a few links to really good supporting information.
If you must go that route, however, then yes, the BLOB field (or a VarBinary(MAX) in SQLServer) is the way to do it. You can retrieve those images as Byte[] data.
I ask this question as a followup of this question.
A solution that uses bcp and xp_cmdshell, that is not my desired solution, has been posted here.
I am new to c# (since I am a Delphi developer) anyway I was able to create a simple CLR stored procedure by following a tutorial.
My task is to move a file from the client file system to the server file system (the server can be accessed using remote IP, so I cannot use a shared folder as destination, this is why I need a CLR stored procedure).
So I plan to:
store from Delphi the file in a varbinary(max) column of a temporary table
call the CLR stored procedure to create a file at the desired path using the data contained in the varbinary(max) field
Imagine I need to move C:\MyFile.pdf to Z:\MyFile.pdf, where C: is a harddrive on local system and Z: is an harddrive on the server. C is in New York, Z is in London and there is no VPN between them, just https connection.
I provide the code below (not working) that someone can modify to make it work? Here I suppose to have a table called MyTable with two fields: ID (int) and DATA (varbinary(max)). Please note it doesn't make a difference if the table is a real temporary table or just a table where I temporarly store the data. I would appreciate if some exception handling code is there (so that I can manage an "impossible to save file" exception).
I would like to be able to write a new file or overwrite the file if already existing.
[Microsoft.SqlServer.Server.SqlProcedure]
public static void VarbinaryToFile(int TableId)
{
using (SqlConnection connection = new SqlConnection("context connection=true"))
{
connection.Open();
SqlCommand command = new SqlCommand("select data from mytable where ID = #TableId", connection);
command.Parameters.AddWithValue("#TableId", TableId);
// This was the sample code I found to run a query
//SqlContext.Pipe.ExecuteAndSend(command);
// instead I need something like this (THIS IS META_SYNTAX!!!):
SqlContext.Pipe.ResultAsStream.SaveToFile('z:\MyFile.pdf');
}
}
(one subquestion is: is this approach correct or there is a way to directly pass the data to the CLR stored procedure so I don't need to use a temp table?)
If the subquestion's answer is No, could you describe the approach of avoiding a temp table? So is there a better way then the one I describe above (=temp table + Stored procedure)? A way to directly pass the dataastream from the client application to the CLR stored procedure? (my files can be any size but also very big)
is [there] a way to directly pass the data to the CLR stored procedure so I don't need to use a temp table?
Yes, it is both possible and rather simple to pass a binary file to a SQLCLR stored procedure and have it write the contents to disk, and not require first placing those contents into a table--temporary or real.
[Microsoft.SqlServer.Server.SqlProcedure]
public static void SaveFileToLocalDisk([SqlFacet(MaxSize = -1)] SqlBytes FileContents,
SqlString DestinationPath)
{
if (FileContents.IsNull || DestinationPath.IsNull)
{
throw new ArgumentException("Seriously?");
}
File.WriteAllBytes(DestinationPath.Value, FileContents.Buffer);
return;
}
Or, since you said that the files are sometimes large, the following should be much easier on memory usage as it makes use of the streaming functionality:
[Microsoft.SqlServer.Server.SqlProcedure]
public static void SaveFileToLocalDiskStreamed(
[SqlFacet(MaxSize = -1)] SqlBytes FileContents, SqlString DestinationPath)
{
if (FileContents.IsNull || DestinationPath.IsNull)
{
throw new ArgumentException("Seriously?");
}
int _ChunkSize = 1024;
byte[] _Buffer = new byte[_ChunkSize];
using (FileStream _File = new FileStream(DestinationPath.Value, FileMode.Create))
{
long _Position = 0;
long _BytesRead = 0;
while (true)
{
_BytesRead = FileContents.Read(_Position, _Buffer, 0, _ChunkSize);
_File.Write(_Buffer, 0, (int)_BytesRead);
_Position += _ChunkSize;
if (_BytesRead < _ChunkSize || (_Position >= FileContents.Length))
{
break;
}
}
_File.Close();
}
return;
}
The assembly containing this code will, of course, need to have a PERMISSION_SET of EXTERNAL_ACCESS.
In both cases, you would execute them in the following manner:
EXEC dbo.SaveFileToLocalDiskStreamed 0x2A20202A, N'C:\TEMP\SaveToDiskTest.txt';
And "0x2A20202A" should give you a file containing the following 4 characters (asterisk, space, space, asterisk):
* *
See http://www.mssqltips.com/tip.asp?tip=1662
Why are you putting these files into database? If you have http/https connection you can upload the file to the server, write into a protected dierctory and create a page to list those files and give a link to download it. If you want to store some extra information you can write it into database. You just need to change the name of file at server side (use a unique name).
After some research I conclude that it makes no sense, it is better to drop the support of 2005 and use 2008 fielstream feature. I can have a conditional logic to choose between 2005 and 2008 and use filestream only for 2005.
I have a project in C# using Microsoft Office Access for storage. I can read and save to the database.
Now I need to allow the user to use the new database project but structured like the working one, and also to implement Save As option.
Besides I need to export to a text file/CSV.
Any ideas or sample codes would be helpful.
One way to create a blank DB is to try the following
using System;
using ADOX;
public class CreateDB
{
public static void Main( string [] args )
{
ADOX.CatalogClass cat = new ADOX.CatalogClass();
string create =
#"Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\BlankAccessDB\MyAccessDBCreatedFromCsharp.mdb;" +
"Jet OLEDB:Engine Type=5";
cat.Create(create);
cat = null;
}
}
Both Save and SaveAs is as easy as using SaveFileDialog to prompt the user to specify the filename and location to save the file.
The way I did this was to create a new empty access database file (this comes to about 100 KB) and then embed that file as a resource in my application. To "create" a new database is then simply a matter of extracting the resource to a file - which gives you a blank database - and then running a schema update code to create the schema you require in the blank database and then off you go.
I have a project that contains an empty database set to be embedded, a class with one method as below and, er, that's about it.
This is the code to dump the file from the embedded resource - it's not up to date, I wrote it 6 years ago but have had no need to change it:
public void CreateDatabase(string sPath)
{
// Get the resource and, er write it out?
System.IO.Stream DBStream;
System.IO.StreamReader dbReader;
System.IO.FileStream OutputStream;
OutputStream = new FileStream(sPath, FileMode.Create);
Assembly ass = System.Reflection.Assembly.GetAssembly(this.GetType());
DBStream = ass.GetManifestResourceStream("SoftwareByMurph.blank.mdb");
dbReader = new StreamReader(DBStream);
for(int l=0;l < DBStream.Length;l++)
{
OutputStream.WriteByte((byte)DBStream.ReadByte());
}
OutputStream.Close();
}
Simple, effective and the .dll is 124 KB.
Note I use an utterly blank and empty Access file - attempting to maintain the right schema in the embedded file is going to cause it to grow (because of the way .mdb files work) and may result in shipping data - which probably shouldn't happen. The schema itself is created/updated/maintained by a separate lump of DDL (SQL) that I run from code.
Export to .CSV is moderately trivial to do by hand since you pretty much just need to iterate over the columns in a table but for a smarter approach look at FileHelpers.