Return either blank or numeric value - sql-server-2012

I have looked and looked and can not find an answer anywhere so I am hoping you guys can help me. I am pulling data from multiple tables using a left join. Some info is not in the right table so it pulls across as NULL. The end user is requesting that all NULL values show as blank. I can easily do this for columns with string datatypes but I have not been able to figure out a way to do this for columns with numeric, int, money, or float datatypes.
See screenshot for simplistic example:
Using SQL Sever 2012

Probably not the answer you want to hear but you might need to convert the numeric columns in your result set to a string type (nvarchar, varchar...etc) and then put a CASE WHEN structure in your SELECT around each one of those columns and check if the value of the field is NULL then print '' the blank string.

Try this;
select
NumberNull=case when ISNUMERIC(YourField)=1 then cast(YourField AS varchar(100)) else '' end

Related

SQL add text to numeric column

I'm not sure if this is even possible but I have a query that joins two table and compares two data sets, current month vs previous month. Where I have new data the previous column produces a Null.
I have been trying to replace NULL with the text 'New Account'. However I am aware that I am trying to force a text value into a numeric column.
So I'm just wondering if this is even possible as I haven't found anything online to help.
Thanks in advance.
Just to expand on Gordon's and Larnu's comments.
No, you can't UPDATE a numeric column with text. You can, however, change the final presentation of the value.
Please note that the final result is a string and not a numeric value.
Example
Declare #YourTable table (SomeCol int)
Insert Into #YourTable values
(25)
,(null)
Select SomeCol = coalesce(left(SomeCol,10),'New Account')
From #YourTable
Returns
SomeCol
25
New Account

SQL / PROGRESS Blank in place of NULL Date

I am trying to replace a NULL date with a blank. I end up with invalid date string. Ive Tried COALESCE, ISNULL, IFNULL, CASE STATEMENTS and nothing seems to work. I am querying a LINKED PROGRESS ODBC connection and using
declare #Data varchar(max)
set #Data= N'
SELECT MyCode
FROM TABLE
'
exec (#Data ) AT PROGRESS;
Ive done this many times before, I can do ISNULL, COALESCE etc just fine on all my other fields, but not the case with this Date field. Any help is greatly appreciated
I understand you are accessing a Progress database.
The Progress unknown value ? is what SQL calls NULL.
Date fields can only contain valid dates or (if the field is not mandatory) the unknown value ?. Unlike other data types, unknown values are sometimes displayed as blanks instead of ?, for example when displayed as GUI widgets.
There are no actual blank dates in Progress.
Unfortunately I don't know enough SQL to tell exactly what you are trying to achieve.
I had to make my query an open query and in the outer select do ISNULL(datefield,'')

Alter column from varchar to decimal when nulls exist

How do I alter a sql varchar column to a decimal column when there are nulls in the data?
I thought:
ALTER TABLE table1
ALTER COLUMN data decimal(19,6)
But I just get an error, I assume because of the nulls:
Error converting data type varchar to numeric. The statement has been terminated.
So I thought to remove the nulls I could just set them to zero:
ALTER TABLE table1
ALTER COLUMN data decimal(19,6) NOT NULL DEFAULT 0
but I dont seem to have the correct syntax.
Whats the best way to convert this column?
edit
People have suggested it's not the nulls that are causing me the problem, but non-numeric data. Is there an easy way to find the non-numeric data and either disregard it, or highlight it so I can correct it.
If it were just the presence of NULLs, I would just opt for doing this before the alter column:
update table1 set data = '0' where data is null
That would ensure all nulls are gone and you could successfully convert.
However, I wouldn't be too certain of your assumption. It seems to me that your new column is perfectly capable of handling NULL values since you haven't specified not null for it.
What I'd be looking for is values that aren't NULL but also aren't something you could turn in to a real numeric value, such as what you get if you do:
insert into table1 (data) values ('paxdiablo is good-looking')
though some may argue that should be treated a 0, a false-y value :-)
The presence of non-NULL, non-numeric data seems far more likely to be causing your specific issue here.
As to how to solve that, you're going to need a where clause that can recognise whether a varchar column is a valid numeric value and, if not, change it to '0' or NULL, depending on your needs.
I'm not sure if SQL Server has regex support but, if so, that'd be the first avenue I'd investigate.
Alternatively, provided you understand the limitations (a), you could use isnumeric() with something like:
update table1 set data = NULL where isnumeric(data) = 0
This will force all non-numeric values to NULL before you try to convert the column type.
And, please, for the love of whatever deities you believe in, back up your data before attempting any of these operations.
If none of those above solutions work, it may be worth adding a brand new column and populating bit by bit. In other words set it to NULL to start with, and then find a series of updates that will copy data to this new column.
Once you're happy that all data has been copied, you should then have a series of updates you can run in a single transaction if you want to do the conversion in one fell swoop. Drop the new column and then do the whole lot in a single operation:
create new column;
perform all updates to copy data;
drop old column;
rename new column to old name.
(a) From the linked page:
ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($).
Possible solution:
CREATE TABLE test
(
data VARCHAR(100)
)
GO
INSERT INTO test VALUES ('19.01');
INSERT INTO test VALUES ('23.41');
ALTER TABLE test ADD data_new decimal(19,6)
GO
UPDATE test SET data_new = CAST(data AS decimal(19,6));
ALTER TABLE test DROP COLUMN data
GO
EXEC sp_RENAME 'test.data_new' , 'data', 'COLUMN'
As people have said, that error doesn't come from nulls, it comes from varchar values that can't be converted to decimal. Most typical reason for this I've found (after checking that the column doesn't contain any logically false values, like non-digit characters or double comma values) is when your varchar values use comma for decimal pointer, as opposed to period.
For instance, if you run the following:
DECLARE #T VARCHAR(256)
SET #T = '5,6'
SELECT #T, CAST(#T AS DEC(32,2))
You will get an error.
Instead:
DECLARE #T VARCHAR(256)
SET #T = '5,6'
-- Let's change the comma to a period
SELECT #T = REPLACE(#T,',','.')
SELECT #T, CAST(#T AS DEC(32,2)) -- Now it works!
Should be easy enough to look if your column has these cases, and run the appropriate update before your ALTER COLUMN, if this is the cause.
You could also just use a similar idea and make a regex search on the column for all values that don't match digit / digit+'.'+digit criteria, but i suck with regex so someone else can help with that. :)
Also, the american system uses weird separators like the number '123100.5', which would appear as '123,100.5', so in those cases you might want to just replace the commas with empty strings and try then?

SQL Express 2010 how to remove empty text fields from a select query

I've been banging my head against a brick wall for this for ages.
I am trying to query a table in SQL Express 2010. There are about ten fields in the table. One of the fields is a text field. Some of these have text in them, some have none (I am presuming that they are empty rather than null because querying with Is Null returns an empty set). I want to return the records which have text in this field and not those which are empty. I am guessing that they are empty rather than a blank space.
I have tried the NullIf and IsNull combinations I have seen posted in a few forums but the syntax in these are causing errors. When I put in ' ' as the empty string it is highlighted in red as an error and executing the query just returns an error about can not find such and such with this column name. Sorry I don't have the exact phrase, I'm also having problems with a monitor, etc, etc...
Hope you can help, let me know if you need any more info.
Thanks!
This bit of code shows how to handle NULL and/or "emptry string" text fields:
CREATE TABLE #TextTest (
ID INT IDENTITY,
TextCol TEXT
)
--Add 2 rows with data, 1 with NULL, 1 with "empty string".
INSERT INTO #TextTest (TextCol)
VALUES ('123'),('456'), (NULL), ('')
--This should succeed, but returns the one row with the "empty string".
SELECT *
FROM #TextTest
WHERE TextCol IS NOT NULL
--This should fail
SELECT *
FROM #TextTest
WHERE TextCol <> ''
--This should succeed.
SELECT *
FROM #TextTest
WHERE CAST(TextCol AS VARCHAR(MAX)) <> ''
--Clean up temp table when finished.
--DROP TABLE #TextTest
NOTE: ntext, text, and image data types will be removed in a future version of Microsoft SQL Server. Avoid using these data types in new development work, and plan to modify applications that currently use them. Use nvarchar(max), varchar(max), and varbinary(max) instead.

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.