How to use a default in SELECT query? - sql

I have created a default value like this:
create default [dbo].[MAX_DATE] as '31/12/9999 23:59:59'
Now I would like to return it from a sql query. I tried this:
SELECT
CASE date_field WHEN dbo.MAX_DATE THEN '' ELSE date_field END
FROM
myTable
However, I get the following error:
Server: Msg 107, Level 16, State 2, Line 2
The column prefix 'dbo' does not match with a table name or alias name used in the query.

Defaults are used by binding them to columns. The default value is applied by the server when a row is created and a column value isn't specified. (See: http://msdn.microsoft.com/en-us/library/ms173565.aspx)
Here are 3 options for you:
Option (1)
It looks like you're using a "named constant" for use in doing compares. In this case, you might want to go with a function, such as:
CREATE Function [dbo].[MAX_DATE] ()
Returns Datetime
as
BEGIN
Return '99991231 23:59:59'
END;
GO
select dbo.MAX_DATE()
Option (2)
Another option you might consider is having a table of named constants. It might have the columns: ID (autonumber), ValueName, numValue, strValue, dtValue, binValue. You would populate the ValueName and the appropriate column depending on what type of value you're storing in it.
Option (3)
To use a constant in just your current script, you can declare a value and set it's value and use it in the rest of your script. These variables are out of scope outside of their batch, so either when the script has finished running, or SQL encounters a GO statement. E.g.
DECLARE #MAX_VALUE as datetime
set #MAX_VALUE = '99991231 23:59:59'
select #MAX_VALUE

Related

SQL statement to change the value of a column with that same column in the where clause

I have a SQL Server database and I've changed my mind and instead of a column in my table being set as an int, I want to change it to a varchar. So I changed the type to varchar(8), and saved my changes in SQL Server Management Studio tool (V17.0).
It looks like the tool converted the int values to varchars when I saved the changes. I want to change the value of '1' to 'External', '2' to 'SPTR' and '3' to 'Other'. I was going to do one value at a time.
This is the simple SQL statement I tried:
UPDATE mytable
SET mycolumn = 'External'
WHERE mycolumn = '1'
The error message I get from SSMS is
Conversion failed when converting the varchar value 'External' to data type int"
It's as if the database thinks the type is int, but it's not, it's varchar(8).
Sounds like you really haven't changed the data type. This should resolve the problem.
ALTER TABLE mytable ALTER COLUMN mycolumn varchar(8);
GO
UPDATE mytable
SET mycolumn = CASE mycolumn WHEN '1' THEN 'External'
WHEN '2' THEN 'SPTR'
ELSE 'OTHER'
END;
Note, as well, you can update every value at the same time by using a CASE expression. Likely far easier than 3 UPDATE statements.
ALTER TABLE mytable ALTER COLUMN mycolumn varchar(50);
SELECT DATALENGTH ('External')
returns 8
As long as I know varchar does not use all 50 bytes, it only uses 8 in your case to store "External" field, why don't you try to change table size.
If you have changed mycolumn to a string, then the following should work:
UPDATE mytable
SET mycolumn = 'External'
WHERE mycolumn = '1';
If you are getting a type conversion error, then I assume you have a trigger on the table that is causing the problem. You might be wrong in saying that the type has changed. But even if you are correct, a trigger could still generate this issue.

SQL Parameter Compare to Whitelist Column Values

I have a table that has a whitelist of all valid domains. The column in question is called "URL"
URL column is VARCHAR(60) and #url is a .Net string primitive.
I want a SQL statement that returns "1" if the SQL parameter provided starts with the whitelisted URLs I have stored on my table. This is what I have:
SELECT 1
FROM [TABLE]
WHERE #url LIKE (URL || '%')
But it doesn't work and gives the following error:
A LIKE predicate or POSSTR scalar function is not valid because the first operand is not a string expression or the second operand is not a string.
An example of what I'd like to happen is when given the parameter value of HTTP://WWW.GOOGLE.COM/ANYTHING/AFTER/THIS and there is a row on my table that looks like HTTP://WWW.GOOGLE.COM it will return "1", but if there is not a row that starts with the domain then return null.
Example table values:
HTTP://WWW.GOOGLE.COM
HTTPS://WWW.ANOTHERWEBSITE.GOV
HTTP://WWW.DOMAIN.CORP
HTTP://MY.WEBSITE.COM
HTTPS://STUFF/SUBDOMAIN/
HTTP://BUSINESS.JUNK.CORP/
How about:
SELECT 1
FROM table
WHERE LEFT(URL, LENGTH(#url)) = #url;
or
SELECT 1
FROM table
WHERE LOCATE(URL, #url,1) = 1;
EDIT:
Depending of your datatypes I suggest to use cast:
CAST(URL AS VARCHAR(100)) -- instead of URL
CAST(#url AS VARCHAR(100)) -- instead of #url
EDIT FROM POSTER:
The combination of the above solutions solved my problem, I'll post the SQL that I used below:
SELECT 1
FROM table
WHERE LOCATE(URL, CAST(#url AS VARCHAR(60)), 1) = 1

comparing input parameter with xml value using like in sql

I have an SQL table with a column which stores xml like this
<AdditionalInfo><RegistrantID>16279</RegistrantID></AdditionalInfo>
I have created a stored procedure like this:
CREATE PROC hr_GetJobStatusByRegistrantId
#registrantId VARCHAR
AS
BEGIN
SELECT TOP 1
[IsSubscribed]
FROM [Hrge].[dbo].[hr_Jobs]
where AdditionalInfo LIKE '%<AdditionalInfo><RegistrantID>%' + #registrantId + '%</RegistrantID></AdditionalInfo>%'
END
When I run this stored procedure, I get null:
exec hr_GetJobStatusByRegistrantId '16279'
If I make this parameter integer then I get convertion to int error.
Please suggest me solution to this.
(Just expanding the comment into an answer)
You should always specify the width of a char or a varchar field, because unless you do the default kicks in. The documentation says:
When n is not specified in a data definition or variable declaration
statement, the default length is 1. When n is not specified when using
the CAST and CONVERT functions, the default length is 30.
which means that in your case you have actually defined #registrantId as VARCHAR(1) so the value of '16279' was trimmed to a single character ('1') and you actually searched for
%<AdditionalInfo><RegistrantID>%1%</RegistrantID></AdditionalInfo>%
in the database. This actually returned the IsSubscribed flag for the first record it found in the DB that had a '1' anywhere in the RegistrantID field. You got lucky that the value was something wrong, so you noticed it.
Additionally you are using % around your parameter. This means that when you search for a RegistrantID of 123, you'll get results for 123, 1234, 2123, 51236, etc, etc, and then just take the first one, whichever that one is (decided by the database, since there is no order clause). It's my guess that you need an exact match, so you should remove those, and just use
'%<AdditionalInfo><RegistrantID>' + #registrantId
+ '</RegistrantID></AdditionalInfo>%'
Also, it the RegistrantId is actually a number, it would be nice if the interface of the procedure reflected that, so it could be defined with
#registrantId int
and then converted to a string in the query
'%<AdditionalInfo><RegistrantID>' + cast(#registrantId as varchar(10))
+ '</RegistrantID></AdditionalInfo>%'

Using Cell content as a parameter of a Function in SQL Server Query

I just Started working with SQL Server and I want to set one column of my table based on another column(automatically and both columns are in a same table). I've wrote a function like this:
ALTER FUNCTION [dbo].[FloorNameConvertor]
(
#Number int
)
RETURNS nchar(10)
AS
BEGIN
RETURN
( CASE
WHEN #Number/100=1 THEN 'x'
WHEN #Number/100=2 THEN 'y'
ELSE 'w'
END
)
END
and I use it in default value of my column properties. I have problem to send a value of the cell as a parameter ( I can't select one cell )?
Thanks
You cannot use other column names in default constraints. You can work it around with INSTEAD OF INSERT trigger or use computed column (not persisted though).

SQLSTATE[22P02]: Invalid text representation

I'm using Postgresql and PHP 5.3.x with PDO to access the DB.
I have this the SQL query (stripped down version), with a placeholder for PDO to fill in:
INSERT INTO t_articles (a_article_id) VALUES (?) RETURNING a_id
I want a_article_id to be either a number, like 5, or else it should be the result of the subquery:
((SELECT max(a_article_id) FROM t_articles) + 1)
However, PDO says:
SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "(SELECT max(a_article_id) FROM t_articles) + 1"
And I've tried to set the subquery as the default value, but it is not allowed apparently:
ERROR: cannot use sub query in default expression
How can I insert the result of this sub query (or what can be done to achieve the same result)?
You'd have to use INSERT...SELECT for that:
insert into t_articles (a_article_id)
select max(a_article_id) + 1
from t_articles
returning id
Or if you don't need contiguous values for a_article_id, use a sequence for it:
Create a sequence, we'll call it article_id_sequence.
-- Get the current max(a_article_id)+1 to use instead of FIRST_VAL below
create sequence article_id_sequence
start FIRST_VAL
owned by t_articles.a_article_id;
Set the default value for t_articles.a_article_id to nextval('article_id_sequence').
alter table t_articles
alter column a_article_id
set default nextval('article_id_sequence');
Use the default value when inserting:
insert into t_articles (a_article_id)
values (default)
returning id;