SQL Server Ce 2005 Data Conversion fails based on data in table - sql

I have a query like :
select * from table where varchar_column=Numeric_value
that is fine until I run an insert script. After the new data is inserted, I must use this query:
select * from table where varchar_column='Numeric_value'
Can inserting a certain kind of data cause it to no longer implicitly convert?
After the insert script, the error is Data conversion fails OLEDB Status = 2
And the second query does work

I'm not certain of this... the first may be doing an implicit conversion of the varchar_column to a numeric value. Not the other way around. But when you insert values into that column that's no longer convertable, it fails. However, with the second, you're doing a varchar to varchar comparison and all is right again with the world. My guess.

Related

Binary or string data would be truncated

I am running an insert statement to populate records into a table using SQL Server 2012. In table 1 that has all the records, the datatype is VARCHAR(5000), and I have done a max(len) to determine that the maximum length of data it contains is about 3000.
In table 2 that the records should go into, the datatype for the field is VARCHAR(5000), which mirrors what's in Table 1.
I am getting the dreaded binary or string data would be truncated message, but my destination table field is large enough to store this data.
When I remove this field from the insert statement, the insert statement works fine and my data moves from Table 1 to Table 2 as expected, but including the field causes this error.
Has anyone come across this peculiar case before? Is it possible that the string field has some sort of weird characters in it that could be causing this error.
Thanks

What is SQL Server 2005 expected behavior of insert into table select query where one of the columns attempts to convert a null value

We have a statement in some legacy SQL Server 2005 code like
insert into myTable
select distinct
wherefield1,
wherefield2,
anotherfield,
convert(numeric(10,2), varcharfield1),
convert(numeric(10,2), varcharfield2),
convert(numeric(10,2), varcharfield3),
convert(datetime, varcharfield4),
otherfields
from myStagingTable
where insertflag='true'
and wherefield1 = #wherevalue1
and wherefield2 = #wherevalue2
Earlier in the code, a variable is set to determine whether varcharfield1 or varcharfield2 is null, and the insert is programmed to execute as long as one of them is not null.
We know that if varcharfield1, varcharfield2, or varcharfield3 is a nonnumeric character string, an exception will be thrown and the insert will not occur. But I am perplexed by the behavior when one of these variables is null, as it often is. Actually, it is always the case that one of these values is null. But it seems that the insertion does take place. It looks like the legacy code relies on this to prevent only insertion of nonnumeric character data, while allowing insertion of null or empty values (in an earlier step, all empty strings in these fields of myStagingTable are replaced with null values).
This has been running on a Production SQL Server 2005 instance with all default settings for a number of years. Is this behavior we can rely on if we upgrade to a newer version of SQL Server?
Thanks,
Rebeccah
conversion of NULL to anything is still NULL. If the column allows NULL, that's what you'll get. If the column is not nullable, it will fail.
You can see this yourself without even doing an INSERT. Just run this:
SELECT CONVERT(numeric(10,2), NULL)
and note how it produces a NULL result. Then run this:
SELECT CONVERT(numeric(10,2), 'x')
and note how it throws an error message instead of returning anything.

Cannot reproduce "string or binary data would be truncated" error

For a 10 minute period yesterday, a SQL stored procedure kept throwing the error "string or binary data would be truncated" when it was executed via my webserver. However, when I ran the exact same SQL command via Microsost SQL Server Management Studio there was no error.
In the SP there is only one insert statement; here's an abstraction of it:
DECLARE #TempTable table (Row1 varchar(25), Row2 varchar(4), Row3 int)
INSERT INTO #TempTable (Row1,Row2,Row3)
SELECT DISTINCT
A.Value
,RIGHT(A.Text,4)
,CAST(ISNULL(A.Thing,'0') as int)
FROM ActivityTable A
In the database Activity table, each of those rows is defined as varchar(25) though Thing is always used for integers (stored as varchar, yes it's stupid). On the face of it I can't see how any of those could exceed the insert column's size.
I tried commenting them out one-by-one, inserting an empty string instead. First I replaced A.Value with '' and refreshed the webpage that executes the procedure; there was no error. I assumed this was the problem column so I put it back to the original value, assuming this would bring back the error. Except it didn't, and since then the error hasn't reoccurred.
This SP has run without issues for months, and only broke for those 10 minutes yesterday. Last week I raised the compatibility level on my SQL server from 100 to 130, so I'm assuming that must be somehow connected. But it also seems to have been affected by me altering the procedure, in addition to being time-specific and user-specific.
1) In code you are declaring table #TempTable and inserting into #Temp
2) A.Value in some cases is longer then 25chars. Try to use LEFT(A.Value,25) instead. Or extend the column size.

SQL Server DBLlink to oracle returns numbers as string

I have an Oracle database containing my data and an SQL Server database getting the data from Oracle through DBLink.
Problem is - all numbers from the Oracle tables are accepted at the SQL Server as nvarchar. As a result, when i try to filter the query in the SQL Server with some_number_field = 0 i get:
"Conversion failed when converting the nvarchar value '3.141' to data type int."
This also happens if i try to select "some_number_field * 1" or similar expressions.
Any idea ?
Today I ran into the same kind of problem. It seems that Oracle field with datatype NUMBER are shown as nvarchar where querying through a linked server. However, NUMBER(x,y) not.
E.g. colB is the NUMBER field from an Oracle View (or table)
Try this:
SELECT colA, CAST(colB AS DECIMAL(23,2)) colB
FROM OPENQUERY(LINKED_SERVER_NAME, 'select * from myView')
Note: the DECIMAL(xx,y) values depends of course on your data. Also, remember, if your NUMBER column is a repetitive fraction (eg. 33.33333333 etc), you need to place a round() on the oracle side otherwise the CAST will throw an error.

How to prevent CAST errors on SSIS?

The question
Is it possible to ask SSIS to cast a value and return NULL in case the cast is not allowed instead of throwing an error ?
My environment
I'm using Visual Studio 2005 and Sql Server 2005 on Windows Server 2003.
The general context
Just in case you're curious, here is my use case. I have to store data coming from somewhere in a generic table (key/value structure with history) witch contains some sort of value that can be strings, numbers or dates. The structure is something like this :
table Values {
Id int,
Date datetime, -- for history
Key nvarchar(50) not null,
Value nvarchar(50),
DateValue datetime,
NumberValue numeric(19,9)
}
I want to put the raw value in the Value column and try to put the same value
in the DateValue column when i'm able to cast it to Datetime
in the NumberValue column when i'm able to cast it to a number
Those two typed columns would make all sort of aggregation and manipulation much easier and faster later.
That's it, now you know why i'm asking this strange question.
============
Thanks in advance for your help.
You could also try a Derived Column component and test the value of the potential date/number field or simply cast it and redirect any errors as being the NULL values for these two fields.
(1) If you just simply cast the field every time with a statement like this in the Derived Column component: (DT_DATE)[MYPOTENTIALDATE] - you can redirect the rows that fail this cast and manipulate the data from there.
OR
(2) You can do something like this in the Derived Column component: ISNULL([MYPOTENTIALDATE]) ? '2099-01-01' : (DT_DATE)[MYPOTENTIALDATE]. I generally send through '2099-01-01' when a date is NULL rather than messing with NULL (works better with Cubes, etc).
Of course (2) won't work if the [MYPOTENTIALDATE] field comes through as other things other than a DATETIME or NULL, i.e., sometimes it is a word like "hello".
Those are the options I would explore, good luck!
In dealing with this same sort of thing I found the error handling in SSIS was not specific enough. My approach has been to actually create an errors table, and query a source table where the data is stored as varchar, and log errors to the error table with something like the below. I have one of the below statements for each column, because it was important for me to know which column failed. Then after I log all errors, I do a INSERT where I select those records in SomeInfo that do not have an errors. In your case you could do more advanced things based on the ColumnName in the errors table to insert default values.
INSERT INTO SomeInfoErrors
([SomeInfoId]
,[ColumnName]
,[Message]
,FailedValue)
SELECT
SomeInfoId,
'PeriodStartDate',
'PeriodStartDate must be in the format MM/DD/YYYY',
PeriodStartDate
FROM
SomeInfo
WHERE
ISDATE(PeriodStartDate) = 0 AND [PeriodStartDate] IS NOT NULL;
Tru using a conditional split and have the records where the data is a date go along one path and the other go along a different path where they are updated to nullbefore being inserted.