Case Expression error (NON- Boolean) - sql-server

I'm getting error when i tried to use case statement please I'm new in SQL Query anyone know where im wrong
An expression of non-boolean type specified in a context where a condition is expected, near 'and'.

You probably want (checking if all columns are true in row):
SELECT
case when (
SIGN(Orcale) * SIGN(Sqlserver) * SIGN(GeoDatabase) * SIGN(Shapefile) *
SIGN(Cadfile) * SIGN(Excel) *SIGN(Word) * SIGN(OtherType)) = 1 then 'u'
ELSE 'Re'
end
FROM tab;
DBFiddle Demo

Assuming, instead of lad2025's answer where all columns are true, that you want to know if ANY column is true, this will work.
SELECT
CASE
WHEN
(Oracle + Sqlserver + GeoDatabase + Shapefile + Cadfile + Excel + Word + OtherType) = 0
THEN 'u'
ELSE 'Re'
END;

Related

Retrieve value of a column after update?

I update a counter (no autoincrement ... not my database ...) with this FDQuery SQL:
UPDATE CountersTables
SET Cnter = Cnter + 1
OUTPUT Inserted.Cnter
WHERE TableName = 'TableName'
I execute FDQuery.ExecSQL and it works: 'Cnter' is incremented.
I need to retrieve the new 'Counter' value but the subsequent command
newvalue := FDQuery.FieldByName('Cnter').AsInteger
Fails with error:
... EDatabaseError ... 'CountersTables: Field 'Cnter' not found.
What is the way to get that value?
TFDQuery.ExecSQL() is meant for queries that don't return records. But you are asking your query to return a record. So use TFDQuery.Open() instead, eg:
FDQuery.SQL.Text :=
'UPDATE CountersTables' +
' SET Cnter = Cnter + 1' +
' OUTPUT Inserted.Cnter' +
' WHERE TableName = :TableName';
FDQuery.ParamByName('TableName').AsString := 'TableName';
FDQuery.Open;
try
NewValue := FDQuery.FieldByName('Cnter').AsInteger;
finally
FDQuery.Close;
end;
If the database you are connected to does not support OUTPUT, UPDATE OUTPUT into a variable shows some alternative ways you can save the updated counter into a local SQL variable/table that you can then SELECT from.
You have also the RETURNING Unified support Ok, doc only shows INSERT SQL but UPDATE works too.
And I should use a substitution variable for tablename

Query fails on "converting character string to smalldatetime data type"

I've been tasked with fixing some SQL code that doesn't work. The query reads from a view against a predicate. The query right now looks like so.
SELECT TOP (100) Beginn
FROM V_LLAMA_Seminare
//Removal of the following line makes the query successful, keeping it breaks it
where Beginn > (select cast (getdate() as smalldatetime))
order by Beginn desc
When I run the above query, I am greeted with the following error.
Msg 295, Level 16, State 3, Line 1
Conversion failed when converting character string to smalldatetime data type.
I decided to remove the WHERE clause, and now it runs returning 100 rows.
At first, I thought that behind the scenes, SQL Server was somehow including my predicate when bringing back the View . But then I investigated how the View was being created, especially the Beginn field, and at no point does it return a String.
Long story short, the column that becomes the Beginn field is a BIGINT timestamp like 201604201369.... The original user transforms this BIGINT to a smalldatetime using the following magic.
....
CASE WHEN ma.datum_dt = 0
THEN null
ELSE CONVERT(smalldatetime, SUBSTRING(CAST(ma.datum_dt AS varchar(max)),0,5) + '-' +
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),5,2) + '-' +
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),7,2) + ' ' +
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),9,2) +':'+
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),11,2) +':' +
RIGHT(CAST(ma.datum_dt AS varchar(max)),2)) END AS Beginn
...
My last attempt at finding the problem was to query the view and run the function ISDATE over the Beginn column and see if it returned a 0 which it never did.
So my question is two fold, "Why does a predicate break something" and two "Where on earth is this string error coming from when the Beginn value is being formed from a BIGINT".
Any help is greatly appreciated.
This problem is culture related...
Try this and then change the first SET LANGUAGE to GERMAN
SET LANGUAGE ENGLISH;
DECLARE #bi BIGINT=20160428001600;
SELECT CASE WHEN #bi = 0
THEN null
ELSE CONVERT(datetime, SUBSTRING(CAST(#bi AS varchar(max)),0,5) + '-' +
SUBSTRING(CAST(#bi AS varchar(max)),5,2) + '-' +
SUBSTRING(CAST(#bi AS varchar(max)),7,2) + ' ' +
SUBSTRING(CAST(#bi AS varchar(max)),9,2) +':'+
SUBSTRING(CAST(#bi AS varchar(max)),11,2) +':' +
RIGHT(CAST(#bi AS varchar(max)),2)) END AS Beginn
It is a very bad habit to think, that date values look the same everywhere (Oh no, my small application will never go international ...)
Try to stick to culture independent formats like ODBC or ISO
EDIT
A very easy solution for you actually was to replace the blank with a "T"
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),7,2) + 'T' +
Then it's ISO 8601 and will convert...
The solution was found after looking through #Shnugo's comment. When I took my query which contained the Bigint->Datetime conversion logic, and put it into a CTE with "TOP 100000000" to avoid any implicit conversion actions, my query worked. Here is what my view looks like now with some unimportant parts omitted.
---Important part---
CREATE VIEW [dbo].[V_SomeView] AS
WITH CTE AS (
SELECT TOP 1000000000 ma.id AS MA_ID,
---Important part---
vko.extkey AS ID_VKO,
vko.text AS Verkaufsorganisation,
fi.f7000 AS MDM_Nr,
vf.f7105 AS SAPKdnr,
CASE WHEN ma.datum_dt = 0 --Conversion logic
CASE WHEN ma.endedatum_dt = 0 --Conversion logic
CONVERT(NVARCHAR(MAX),art.text) AS Art,
.....
FROM [ucrm].[dbo].[CRM_MA] ma,
[ucrm].[dbo].[CRM_fi] fi,
[ucrm].[dbo].[CRM_vf] vf,
[ucrm].[dbo].[CRM_ka] vko,
[ucrm].[dbo].[CRM_ka] art,
[ucrm].[dbo].[CRM_ka] kat
where ma.loskz = 0
and fi.loskz = 0
and vf.loskz = 0
and fi.F7029 = 0
and vf.F7023 = 0
...
GROUP BY ma.id,
vko.extkey,
vko.text,
fi.f7000 ,
vf.f7105,
ma.datum_dt,
ma.endedatum_dt,
....
)
select * FROM CTE;

Update table column using table in another SQL Server database while using a spatial function

I would like to update a table column using a spatial function with another database table. This is what I've come up with....
UPDATE FirstDatabase.dbo.track_logs
SET county = t2.CountyName
FROM OtherDatabase.dbo.tblCounty AS t2
WHERE t2.cty_geog.STIntersects(
GEOGRAPHY::STPointFromText('Point(' + FirstDatabase.dbo.track_logs.lng + ' ' +
FirstDatabase.dbo.track_logs.lat + ')', 26915)
)
but I get this error...
An expression of non-boolean type specified in a context where a condition is expected, near ')'.
Almost there. This is one of those silly things in TSQL. You need a = 1.
That's the answer to your question, but I would also be tempted to use POINT(lat, lon, SRID) to address your comment.
UPDATE FirstDatabase.dbo.track_logs
SET county = t2.CountyName
FROM OtherDatabase.dbo.tblCounty AS t2
WHERE t2.cty_geog.STIntersects(geography::Point(FirstDatabase.dbo.track_logs.lat,
FirstDatabase.dbo.track_logs.lng,
26915)) = 1
In a language like C#, you could write something like:
bool val = true;
if (val)
// do stuff
But in TSQL, you have to write the equivalent to:
bool val = true;
if (val == true)
// do stuff
This isn't specific to SQL Spatial, of course, you'd also have to specify WHERE bitColumnName = 1 or, as your example illustrates, WHERE bitReturningFunction(args) = 1.

How can I add text to my column's select statement

I want to prepend text to sql select,
I can do this:
SELECT (1328724983-time)/60/60 AS status
FROM voting
WHERE account = 'ThElitEyeS' AND vid = 1
This will show time left.
What I'd like to do is this though:
SELECT 'Please try after' + (1328724983-time)/60/60 AS status
FROM voting
WHERE account = 'ThElitEyeS' AND vid = 1
Is there any way I can accomplish this?
Just use cast or convert to convert it all to varchar for instance.
SELECT 'Please try after' + CAST((1328724983-time)/60/60 as varchar(80)) AS status
FROM voting
WHERE account = 'ThElitEyeS' AND vid = 1;
See the MSDN on Cast / Convert
Based on your comments you can do:
SELECT 'Please try again after' + CAST(MyColForHours as varchar(25)) + ' hours', AnyOtherColumns FROM Table
Was trying this today and getting an error
SQL0420N Invalid character found in a character string argument of the function "DECFLOAT". SQLSTATE=22018
Apparently we now need to use || instead of + to join the sections.
http://www-01.ibm.com/support/docview.wss?uid=swg21448700

Error converting varchar to numeric with MSSQL

Query
SELECT TOP 1000
CASE WHEN VRI.Square_Footage <> ''
THEN VRI.Square_Footage
ELSE
CASE WHEN VRI.Property_Type = 'LAND'
THEN CAST((CONVERT(NUMERIC(38, 3),VRI.Acres)*43560) AS DECIMAL)
ELSE
VRI.Lot_Size
END
END
FROM View_Report_Information_Tables AS VRI
Even if I checked for VRI.Acres with isnumeric(), it still yield the same exact error? How can I fix this problem?
ISNUMERIC doesn't guarantee that it will successfully cast to decimal.
SELECT ISNUMERIC('£100') /*Returns 1*/
SELECT CONVERT(NUMERIC(38, 3),'£100') /*Error*/
Additionally all branches of the case statement need to return compatible datatypes. It looks like VRI.Square_Footage is a string.
Does this work for you?
SELECT TOP 1000 CASE
WHEN ISNUMERIC(VRI.Square_Footage + 'e0') = 1 THEN
VRI.Square_Footage
WHEN VRI.Property_Type = 'LAND'
AND ISNUMERIC(VRI.Acres + 'e0') = 1 THEN CAST((
CONVERT(NUMERIC(38, 3), VRI.Acres) * 43560 ) AS DECIMAL)
WHEN ISNUMERIC(VRI.Lot_Size + 'e0') = 1 THEN VRI.Lot_Size
END
FROM View_Report_Information_Tables AS VRI
Here run this
SELECT ISNUMERIC('d25')
That can be converted to float but not decimal/numeric
SELECT CONVERT(FLOAT,'2d5')
As you can see, you can't depend on numeric for decimal/numeric data types
Take a look at IsNumeric, IsInt, IsNumber for some code that will show you how you can check

Resources