I am not really sure what I am doing wrong, but it is Monday so this is expected. I am trying to process some data in a table. Occasionally, one of the columns will contain a question mark. I would like to replace all question marks to NULL.
This is my query, but it seems to just replace every single entry.
Update Table
set [Hours] = REPLACE([Hours], '?', NULL)
I have also tried
Update Table
set [Hours] = REPLACE([Hours], CHAR(63), NULL)
I am pretty confident I am missing the simplest mistake. I just can't see it for some reason.
I would rewrite this query to not use a REPLACE
UPDATE Table SET [Hours] = NULL WHERE [Hours] = '?'
EDIT: As for the reason your original query didn't work, as AlexK and roryap say, The docs for REPLACE say that:
Returns NULL if any one of the arguments is NULL.
You can test this by performing a simple replace, such as:
SELECT REPLACE('asdf', '?', NULL)
This will return null, even though ? isn't in the search string.
Use a where clause;
Update Table set [Hours] = NULL
where [Hours] like '%?%'
According to http://technet.microsoft.com/en-us/library/ms186862.aspx, REPLACE
Returns NULL if any one of the arguments is NULL.
Use the WHERE clause, as suggested by the other answers:
UPDATE Table SET [Hours] = NULL WHERE [Hours] = '?'
Try this instead
update table set Hours = null where Hours='?'
Related
I have a stored procedure that includes a table variable which updates from other table variables. ISNULL() is not working in the below code. It returns the proper value if there is something in TR.TotalRequestCnt, but NULL if there is no value in the TotalRequest table for this column.
UPDATE #OutputTable
SET TotalRequestCount = ISNULL(TR.TotalRequestCnt, 0)
FROM #TotalRequest TR
JOIN #OutputTable OT
ON TR.Document = OT.Document
Values of Document are identifying INTs (5577,5575, 5574).
#TotalRequest values are all INT:
5577 NULL NULL
5575 NULL NULL
5574 2 1
I have also tried using COALESCE() instead of ISNULL() to no success.
I found the answer.
No update is being performed in the row at all because there are no values so ISNULL never has the chance to fire.
I created a stored procedure (spBalanceRange) with 2 optional parameters. They've been set to a default value and the sp works fine when I pass only 1 value per parameter by position. However, I have a situation where I'm trying to pass, by position, two strings immediately followed by a wildcard. I want the user to be able to search for Vendor names that start with either 'C%' or 'F%'. Here's the gist of the CREATE PROC statement:
CREATE PROC spBalanceRange
#VendorVar varchar(40) = '%',
#BalanceMin money = 1.0
...
Here's what I've tried so far, but doesn't work:
EXEC spBalanceRange '(C%|F%)', 200.00;
EXEC spBalanceRange 'C%|F%', 200.00;
Is there a way to check for 2 or more string values with a wildcard when passed by position? Thanks.
EDIT: According to your comments you are looking for the first letter of a vendor's name only.
In this special case I could suggest an easy, not well performing but really simple approach. CHARINDEX returns a number greater than zero, if a character appears within a string. So you just have to pass in all your lookup-first-characters as a simple "chain":
DECLARE #DummyVendors TABLE(VendorName VARCHAR(100));
INSERT INTO #DummyVendors VALUES
('Camel Industries')
,('Fritz and Fox')
,('some other');
DECLARE #ListOfFirstLetters VARCHAR(100)='CF';
SELECT VendorName
FROM #DummyVendors AS dv
WHERE CHARINDEX(LEFT(dv.VendorName,1),#ListOfFirstLetters)>0
This was the former answer
Checking against more than one value needs either a dedicated list of compares
WHERE val=#prm1 OR val=#prm2 OR ... (you know the count before)
...or you use the IN-clause
WHERE LEFT(VenoderName,1) IN ('C','F', ...)
...but you cannot pass the IN-list with a parameter like ... IN(#allValues)
You might think about a created TYPE to pass in all your values like a table and use an INNER JOIN as filter: https://stackoverflow.com/a/337864/5089204 (and a lot of other examples there...)
Or you might think of dynamic SQL: https://stackoverflow.com/a/5192765/5089204
And last but not least you might think of one of the many split string approaches. This is one of my own answers, section "dynamic IN-statement": https://stackoverflow.com/a/33658220/5089204
I'm answering my own question, and maybe other solutions exist but here is what had to happen with my stored procedure in order to pass variables by position:
CREATE PROC spBalanceRange
#VendorVar varchar(40) = '%',
#BalanceMin money = 1.0
AS
IF (#VendorVar = '%' AND #BalanceMin IS NULL OR #BalanceMin = '')
BEGIN
PRINT 'BalanceMin cannot be null.';
END
IF (#VendorVar = % AND #BalanceMin IS NOT NULL)
BEGIN
(sql statement using parameters)
END
EXEC spBalanceRange '[C,F]%', 200.00;
That's what I know.
Why #OpeningDate is getting saved as NULL even though I am doing this.
PROCEDURE [dbo].[InsertCaseANDHearingDetails]
#HearingDate datetime,
#IsOpeningDate bit= null,
#OpeningDate date= null,
AS
Begin
IF(#IsOpeningDate = 0)
Begin
Set #OpeningDate= (Select Convert(varchar, #HearingDate, 106))
End
Insert Into Hearings
values (#HearingDate, #OpeningDate)
End
Even though I am calculating it and hearing date is not null but why OpeningDate is getting saved as NULL.
#HearingDate != NULL will not work. The result of this comparison is always unknown. Use #HearingDate is not null instead.
Because the variable #HearingDate is not initialized, it would have a null value.
Also, the variable #OpeningDate wouldn't be set to Select Convert(varchar, #HearingDate, 106) because the if condition evaluates to unknown.
Hence, when you select values from the table they would be null.
Edit:
#IsOpeningDate bit= null
...
IF(#IsOpeningDate = 0)
This condition evaluates to unknown too as this is doing 0 = null. You cannot compare with null.
It will work if you use the following at the start of the Proc.
SET ANSI_NULLS OFF
Basically NULL can't be compared, not even with itself, because this is not a value. If at all, you want the engine to treat it as one, you need to set off the ANSI_NULLS property. That said, I would prefer to go with #vkp's answer any day.
Based on your edit, it looks like the below condition is not met:
IF(#IsOpeningDate = 0)
and hence, it remains NULL.
in the if condition why dont you check is null instead of comparing it to 0
Your query
IF(#IsOpeningDate = 0)
My suggestion
IF(#IsOpeningDate IS NULL)
Sorry it was my mistake to no mention parameters in Insert statement and since NULL were allowed so it inserted NULLs
Thanks for your help as it led me to figure out that what's actually going on.
I'm using C# to write to a SQL Compact Edition 3.5 database. I got a table containing e-mail addresses and names for each address.
MailRecipientAddressID int primary key identity(1,1) not null,
Address nvarchar(4000),
Name nvarchar(4000)
In this table I want every address-name combination to be unique. In some cases it's possible that either Address or Name is NULL in a row. Before inserting new rows into this table, I'm using a SELECT query to check if there is an existing row matching the one I want to insert. When using this query
SELECT MailRecipientAddressID FROM MailRecipientAddress WHERE Address = #Address AND Name = #Name
I will not find existing rows with NULL values in one column (see here).
Now I got this query, which works and kind of solves my problem
SELECT MailRecipientAddressID FROM MailRecipientAddress WHERE ISNULL(Address, '') = ISNULL(#Address, '') AND ISNULL(Name, '') = ISNULL(#Name, '')
but even though it is no problem in my case that NULL and empty string values are handled equally, I do not like this solution. I think it's kind of hackish. Is there a better approach
to apply a filter on a SELECT statement with parameters which can contain NULL
which works on SQL CE
Edit
I do not understand why, but my query works with SQL Management Studio but it does not in my application (see here). To correct my own approach I would need to use COALESCE.
I don't like the option to replace my NULL values with empty strings because I think it would be kind of inconsequent to set a value at a place where I got no value or is my understanding of this design question wrong?
The best solution is a constraint on the table that prevents duplicates from going into the table. You can put one in with a unique index:
create unique index idx_MailRecipientAddress_address_name on MailRecipientAddress(Address, Name);
This will generate an error on the insert, which you would then need to catch.
However, this is only a partial solution, because NULL values do not count as duplicates. You might solve your overall problem by not allowing NULL values in the field at all. Instead, represent no data using empty strings. Note: I wouldn't normally recommend this. In SQL, NULL means "unknown" and by the definition of the language, two "unknown" values are not equal. However, you seem to want them to be equal.
As for SQL, yours is okay, but it equates NULL and the empty string. An explicit check is more accurate:
WHERE (Address = #Address or Address is null and #Address is null) and
(Name = #Name or Name is null and #Name is null)
#George
if Parameter value is Null and column value is not null then "(Address = #Address or Address is NULL) returns false "
if Parameter value is Null and column value is null then "(Address = #Address or Address is NULL) returns true"
if Parameter value is Not Null and column value is null then "(Address = #Address or Address is NULL) returns true"
if Parameter value is Not Null and column value is Not null and if matches then "(Address = #Address or Address is NULL) returns true otherwise false"
SELECT MailRecipientAddressID FROM MailRecipientAddress WHERE (Address = #Address or Address is NULL) AND (Name = #Name or Name is NULL)
How do I clear the value from a cell and make it NULL?
I think Zack properly answered the question but just to cover all the bases:
Update myTable set MyColumn = NULL
This would set the entire column to null as the Question Title asks.
To set a specific row on a specific column to null use:
Update myTable set MyColumn = NULL where Field = Condition.
This would set a specific cell to null as the inner question asks.
If you've opened a table and you want to clear an existing value to NULL, click on the value, and press Ctrl+0.
If you are using the table interface you can type in NULL (all caps)
otherwise you can run an update statement where you could:
Update table set ColumnName = NULL where [Filter for record here]
Use This:
Update Table Set Column = CAST(NULL As Column Type) where Condition
Like This:
Update News Set Title = CAST(NULL As nvarchar(100)) Where ID = 50
Ctrl+0 or empty the value and hit enter.
Just as a little extension to Jeff Martin's and Zack Peterson's solution.
If you still want to set several values from the columns to null you can simply set the query to
UPDATE myTable SET MyColumn1 = NULL, MyColumn2 = NULL, MyColumn3 = NULL, ...
CTRL+0 doesn't seem to work when connected to an Azure DB.
However, to create an empty string, you can always just hit 'anykey then delete' inside a cell.