knowing if a string will be truncated when updating database - c#

I'm working on a software that takes a csv file and put the data in a sqlserver. i'm testing it with bad data now and when i make a data string to long (in a line) to be imported in the database i got the error : String or binary data would be truncated the statement has been terminate. that's normal and that's what i should expect. Now i wanna detecte those error before the update to the database. Is there any clever way to detecte this?
The way my software work is that i importe every line in a dataset then show the user the data that will be imported. Then he can click a button to do the actual update. i then do a dataAdapter.Update( Dataset, "something" ) to make the update to the database.
The probleme is that the error row terminate all the update and report the error. So i want to detect the error before i do the update to the server so the other rows will be inserted.
thanks

You will have to check the columns of each row. See if one exceeds the maximum specified in the database, and if yes, exclude it from being inserted.
A different solution would be to explicitly truncate the data and insert the truncated content, which could be done by using SubString.

The only way that I know of is to pre-check the information schema for the character limit:
Select
Column_Name,
Character_Maximum_Length
From
Information_Schema.Columns
Where
Table_Name = 'YourTableName'

What you need is the column metadata.
MSDN: SqlConnection.GetSchema Method

Or, if you have opened a recordset on your database, another solution would be to browse the field object to use its length to truncate the string. For example, with ADO recordset/VB code, you could have some code like this one:
myRecordset.fields(myField) = left(myString, myRecordset.fields(myField).DefinedSize)

Related

Is there a hard limit as to how many columns can be returned in C# SqlDataAdapter Fill?

I'm currently working on a legacy project that has some SQL needs to run to get some data.
They use DataTables, DataSets, etc to work with the data.
The query in question that gets executed only returns one row, however it contains well over 700 columns.
Unfortunately when the code executes to fill the data set, if the query contains over 655 columns, nothing gets returned.
Is there a way to get around this limitation so if a query returns 656+ columns data will get returned or is there some other workaround?
Thanks!
EDIT:
Chasing a red herring. The data is there, I just can't view it in the debugger as a table if there's 656+ columns in the data. The viewer can't handle more than 655.
The data is there, I just can't view it in the debugger as a table if there's 656+ columns in the data. The viewer can't handle more than 655.
Not sure if it resolve the issue but try using the overloaded Fill method
DbDataAdapter.Fill(Int32, Int32, DataTable[]).
As per MSDN document:
Adds or refreshes rows in a DataTable to match those in the data
source starting at the specified record and retrieving up to the
specified maximum number of records
See here for more http://msdn.microsoft.com/en-us/library/0z5wy74x%28v=vs.110%29.aspx

Updating millions of Row after Calculation

I am looking for advice on how should I do following:
I have a table in SQL server with about 3 -6 Million Records and 51 Columns.
only one column needs to be updated after calculating a value from 45 columns data been taken in mathematical calculation.
I already have maths done through C#, and I am able to create Datatable out of it [with millions record yes].
Now I want to update them into database with most efficient manner. Options I know are
Run update query with every record, as I use loop on data reader to do math and create DataTable.
Create A temporary table and use SQLBulkCopy to copy data and later use MERGE statement
Though it is very HARD to do, but can try to make Function within SQL to do all math and just run simple update without any condition to update all in once.
I am not sure which method is faster one or better one. Any idea?
EDIT: Why I am afraid of using Stored Procedure
First I have no idea how i wrote it, I am pretty new to do this. Though maybe it is time to do it now.
My Formula is Take one column, apply one forumla on them, along with additional constant value [which is also part of Column name], then take all 45 columns and apply another formula.
The resultant will be stored in 46th column.
Thanks.
If you have a field that contains a calculation from other fields in the database, it is best to make it a calculated field or to maintain it through a trigger so that anytime the data is changed from any source, the calculation is maintained.
You can create a .net function which can be called directly from sql here is the link how to create one http://msdn.microsoft.com/en-us/library/w2kae45k%28v=vs.90%29.aspx. After you created the function run the simple update statement
Can't you create a scalar valued function in c#, and call it in as part of a computed column?

When I convert date and time to only time, the cell becomes read only

I would like to understand the concept behind this.
I am making a database in c#. Now, I wish to have only date instead of date and time.
So, I went for the following command in sql query pane:
SELECT CONVERT(varchar, deal_start_date, 101) AS 'deal_start_date'
FROM client
The desired result comes but the data becomes read only and hence cant be edited.
Further, it does not stay permanently. I mean,
On clicking show table data again the date-time format comes.
Can any one tell me why the cells become read-only and how to keep the changes permanently through UI only??
Many thanks.
My guess on the read only part, is that since you are now converting the original value, you loose the link towards the column in the database. Just like a computed column can't be edited (how would you for example write to the column from the query that is defined as A+B as 'C'.
Inside what type of component are you showing this in your GUI? Maybe you can ahve your query remain as SELECT deal_start_date FROM client, and filter out the time part from your component?
Or, if you don't use the time in any other place in your application, change the column from datetime to date in the database.
I did not get a perfect answer but I found an alternative. I was trying with datetime datatype in MS SQL database. When I changed it to varchar(12), I got the desired result. i.e in date format.
(Thanks to insights provided by Øyvind Knobloch-Bråthen )
This is actually improper to follow as with size 12 in varchar, the time part is truncated.
(If the size of varchar is increased, the time part will be present)
But It served my purpose.
But I am still waiting for a correct answer,if any.

How to validate column before importing into database

I am a complete newbie to SSIS.
I have a c#/sql server background.
I would like to know whether it is possible to validate data before it goes into a database. I am grabbing text from a |(pipe) delimited text file.
For example, if a certain datapoint is null, then change it to 0 or if a certain datapoint's length is 0, then change to "nada".
I don't know if this is even possible with SSIS, but it would be most helpful if you can point me into the right direction.
anything is possible with SSIS!
after your flat file data source, use a Derived Column Transformation. Deriving a new column with the expression being something like the following.
ISNULL(ColumnName) ? "nada" : ColumnName
Then use this new column in your data source destination.
Hope it helps.
I don't know if you're dead set on using SSIS, but the basic method I've generally used to import textfile data into a database generally takes two stages:
Use BULK INSERT to load the file into a temporary staging table on the database server; each of the columns in this staging table are something reasonably tolerant of the data they contain, like a varchar(max).
Write up validation routines to update the data in the temporary table and double-check to make sure that it's well-formed according to your needs, then convert the columns into their final formats and push the rows into the destination table.
I like this method mostly because BULK INSERT can be a bit cryptic about the errors it spits out; with a temporary staging table, it's a lot easier to look through your dataset and fix errors on the fly as opposed to rooting through a text file.

how to implement oracle -> oracle conversion/refresher program in C# / ADO.NET 2.0

When program runs 1st time it just gets some fields from a source database table say:
SELECT NUMBER, COLOR, USETYPE, ROOFMATERIALCODE FROM HOUSE; //number is uniq key
it does some in-memory processing say converting USETYPE and ROOFMATERIAL to destination database format (by using cross ref table).
Then program inserts ALL THE ROWS to destination database:
INSERT INTO BUILDING (BUILDINGID, BUILDINGNUMBER, COLOR, BUILDINGTYPE, ROOFMAT)
VALUES (PROGRAM_GENERATED_ID, NUMBER_FROM_HOUSE, COLOR_FROM_HOUSE,
CONVERTED_USETYPE_FROM_HOUSE, CONVERTED_ROOFMATERIALCODE_FROM_HOUSE);
The above is naturally not SQL but you get the idea (the values with underscores just describe the data inserted).
The next times the program should do the same except:
insert only the ones not found from target database.
update only the ones that have updated color, usetype, roofmaterialcode.
My question is:
How to implement this in efficient way?
-Do I first populate DataSet and convert fields to destination format?
-If I use only 1 DataSet how give destination db BUILDING_IDs (can i add columns to populated DataSet?)
-How to efficiently check if destination rows need refresh (if i select them one # time by BUILDING_NUMBER and check all fields it's gonna be slow)?
Thanks for your answers!
-matti
If you are using Oracle, have you looked at the MERGE statement? You give the merge statement a criteria. If records match the criteria, it performs an UPDATE. If they don't match the criteria (they aren't already in the table), it performs an INSERT. That might be helpful for what you are trying to do.
Here is the spec/example of merge.

Categories