How to do calculations with database values in Classic ASP? - sql

I have to do a calculation to an integer value in classic asp, but i keep getting "type mismatch" error on this line: X = tempID + 1
this is my code:
Set TheRS = Conn.Execute("select top 1 xx from W_TABLE order by IDX desc")
tempID = TheRS("xx")
X = tempID + 1
TheRS.Close
Set TheRS = nothing
tempX is of type "User-defined Type"... i'm assuming that's why it wont let me add 1 to it... how can i make this happen?

I've had this problem with numeric/decimal columns. ADO returns the value as a Decimal type, but VBScript doesn't really support the Decimal type. About the only thing you can do with a variable that contains a Decimal type value is convert it using CInt, CDbl, or any of the other conversion functions. My guess is that if you were to inspect the value of VarType(tempID), you would see 14, which corresponds to vbDecimal.
To work around this, you should convert the value using CDbl (or CInt if you don't care about the decimal portion).

Check if the recordset is end of file first. (If TheRS.Eof Then)
It seems to me "xx", whatever that is, isn't actually an integer. Are you sure your query is returning a numerical answer?
Chances are that's why you can't add 1 to it. Try cast it as an integer first: X = CInt(tempID) + 1
Response.Write(tempID) before adding 1 and see what value it has
Not to be rude but that code is indecipherable! W_TABLE? IDX? xx? These are all terrible variable and schema names. I sincerely hope that you have just sanitized your real, appropriately named variables for more abstract, confusing ones.

If you don't want to bother what your database query returns this should do the trick:
X = CInt("0" & tempID) + 1

got it working by changing the select.
select top 1 xx+1 from W_TABLE order by IDX desc
thanks everyone!

Related

Search with inequalities on string property

We are using NHibernate over SQL Server and SQLite.
The database stores records in rows rather than columns -- each row having Path|Value as columns. Path and Value are both string properties.
For certain values of Path we would like to query for inequalities -- greater-than, less-than, etc.
The trouble we are having is that because the properties are strings, the inequalities are using string comparisons -- for example, searching for Value >= 18 returns rows where Value = 5. Unfortunately we are having trouble working around this.
1) This restriction produces incorrect results (saying 18 < 5):
Restrictions.Ge("Value", item.Value);
2) We tried casting the value to an integer, but this code produces a SqlException from NHibernate -- Error converting data type nvarchar to bigint.
Restrictions.Le(Projections.Cast(NHibernateUtil.Int64, Projections.Property("SearchString")), item.Value)
3) We were looking for a way to pad the property value with zeros (so that we would get 018 > 005), but could not find a way to do this in NHibernate.
Does anyone have any advice?
Thank you in advance!
Assuming that you want to compare on integer value, with IQueryOver:
1) This restriction produces incorrect results (saying 18 < 5):
Restrictions.Ge("Value", item.Value);
Restrictions.Ge
(
Projections.Cast(NHibernateUtil.Int32, Projections.Property<YourEntity>(x => x.YourProperty))
, intValue
)
Convert your datatype accordingly. If your C# datatype (intValue) is already numeric, no need to convert it. If your x.YourProperty is already numeric type, no need to convert it. Adjust above code accordingly.
2) We tried casting the value to an integer, but this code produces a SqlException from NHibernate -- Error converting data type nvarchar to bigint.
Restrictions.Le(Projections.Cast(NHibernateUtil.Int64, Projections.Property("SearchString")), item.Value)
Refer the above and check the datatype of item.Value.

I am trying to compare two number using Sql query. for e.g 123.45 and 12345 are same if i ignore decimal so it should come in output

I am trying to compare two string using Sql query. for e.g In table A i have A123.45 and in table B i have A12345. this two string are same if i ignore decimal point so as a output i would want table A's value.
First, to avoid the XY problem, it's a little unclear to me why you'd want to do this in the first place - I'm not sure exactly why 123.45 should be equal to 12345. Definitely something to think about.
With that said, if you insist, you can do something like the following:
select case when replace(cast(floatingPointNumber as varchar(50)), '.', '') = cast(yourInteger as varchar(50)) then 1 else 0 end
from YourTable
Obviously, floatingPointNumber is a float and yourInteger is an integer.
I'm not sure what platform you're using since you didn't tag it but I wrote/tested this in SQL Server. You can do something similar in Oracle/MySQL if that's what you're using.
Basically, what this is doing is casting both the floating point number and the integer to strings, removing the decimal from the floating point number, and comparing them. If they're equal, it returns 1; otherwise it returns 0.

Replacing a calculated field column with a Blank when a NULL is returned?

I'm doing a simple query that uses the DateDiff function to find the number of days between the dates. However, with regards to certain instances, I'd like to populate a blank field (not a null).
Something like this is what I currently have, and it seems to work fine (but it populates a null).
[Test (Years)] = CASE WHEN TYPE IN ('A','B')
THEN NULL ELSE IsNull(CONVERT(decimal(28,12),
(DATEDIFF(d,#StartDate,ExpirationDate)))/365,0) END
Now if I try something like this... which tries to convert all TYPE A and B to populate a blank, I'll get the following error message: Error converting data type varchar to numeric.
[Test (Years)] = CASE WHEN TYPE IN ('A','B')
THEN '' ELSE IsNull(CONVERT(decimal(28,12),
(DATEDIFF(d,#StartDate,ExpirationDate)))/365,0) END
Is there a simple thing I'm missing? I've tried doing the calcualtions without converting to a decimal, but it doesn't seem to work. Any ideas? Thanks
CASE is an expression that returns exactly one value and all of the branches must yield compatible types. A string (even a blank string) is not compatible with a decimal, so you need to do something like:
CASE WHEN ... THEN '' ELSE
CONVERT(VARCHAR(32), COALESCE(CONVERT(DECIMAL(23,12), ... ,0)) END
Note that this hack will only work if you are presenting the data to an end user. If you are trying to store this data in a column or use it in other calculations, it too will be tripped up by the blank string. A number can't be a blank string:
DECLARE #i INT = '';
SELECT #i;
Result:
0
So, if you don't want "empty" numerics to be interpreted as 0, stop being afraid of NULL and if you are dealing with this at presentation time, have the presentation layer present a blank string instead of NULL.

I'm confused about Sqlite comparisons on a text column

I've got an Sqlite database where one of the columns is defined as "TEXT NOT NULL". Some of the values are strings and some can be cast to a DOUBLE and some can be case to INTEGER. Once I've narrowed it down to DOUBLE values, I want to do a query that gets a range of data. Suppose my column is named "Value". Can I do this?
SELECT * FROM Tbl WHERE ... AND Value >= 23 AND Value < 42
Is that going to do some kind of ASCII comparison or a numeric comparison? INTEGER or REAL? Does the BETWEEN operator work the same way?
And what happens if I do this?
SELECT MAX(Value) FROM Tbl WHERE ...
Will it do string or integer or floating-point comparisons?
It is all explained in the Datatypes In SQLite Version 3 article. For example, the answer to the first portion of questions is
An INTEGER or REAL value is less than any TEXT or BLOB value. When an INTEGER or REAL is compared to another INTEGER or REAL, a numerical comparison is performed.
This is why SELECT 9 < '1' and SELECT 9 < '11' both give 1 (true).
The expression "a BETWEEN b AND c" is treated as two separate binary comparisons "a >= b AND a <= c"
The most important point to know is that column type is merely an annotation; SQLite is dynamically typed so each value can have any type.
you cant convert text to integer or double so you wont be able to do what you want.
If the column were varchar you could have a chance by doing:
select *
from Tbl
WHERE ISNUMERIC(Value ) = 1 --condition to avoid a conversion from string to int for example
and cast(value as integer) > 1 --rest of your conditions

Conditionally branching in SQL based on the type of a variable

I'm selecting a value out of a table that can either be an integer or a nvarchar. It's stored as nvarchar. I want to conditionally call a function that will convert this value if it is an integer (that is, if it can be converted into an integer), otherwise I want to select the nvarchar with no conversion.
This is hitting a SQL Server 2005 database.
select case
when T.Value (is integer) then SomeConversionFunction(T.Value)
else T.Value
end as SomeAlias
from SomeTable T
Note that it is the "(is integer)" part that I'm having trouble with. Thanks in advance.
UPDATE
Check the comment on Ian's answer. It explains the why and the what a little better. Thanks to everyone for their thoughts.
select case
when ISNUMERIC(T.Value) then T.Value
else SomeConversionFunction(T.Value)
end as SomeAlias
Also, have you considered using the sql_variant data type?
The result set can only have one type associated with it for each column, you will get an error if the first row converts to an integer and there are strings that follow:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the nvarchar value 'word' to data type int.
try this to see:
create table testing
(
strangevalue nvarchar(10)
)
insert into testing values (1)
insert into testing values ('word')
select * from testing
select
case
when ISNUMERIC(strangevalue)=1 THEN CONVERT(int,strangevalue)
ELSE strangevalue
END
FROM testing
best bet is to return two columns:
select
case
when ISNUMERIC(strangevalue)=1 THEN CONVERT(int,strangevalue)
ELSE NULL
END AS StrangvalueINT
,case
when ISNUMERIC(strangevalue)=1 THEN NULL
ELSE strangevalue
END AS StrangvalueString
FROM testing
or your application can test for numeric and do your special processing.
You can't have a column that is sometimes an integer and sometimes a string. Return the string and check it using int.TryParse() in the client code.
ISNUMERIC. However, this accepts +, - and decimals so more work is needed.
However, you can't have the columns as both datatypes in one go: you'll need 2 columns.
I'd suggest that you deal with this in your client or use an ISNUMERIC replacement
IsNumeric will get you part of the way there. You can then add some further code to check whether it is an integer
for example:
select top 10
case
when isnumeric(mycolumn) = 1 then
case
when convert(int, mycolumn) = mycolumn then
'integer'
else
'number but not an integer'
end
else
'not a number'
end
from mytable
To clarify some other answers, your SQL statement can't return different data types in one column (it looks like the other answers are saying you can't store different data types in one column - yours are all strign represenations).
Therefore, if you use ISNUMERIC or another function, the value will be cast as a string in the table that is returned anyway if there are other strigns being selected.
If you are selecting only one value then it could return a string or a number, however your front end code will need to be able to return the different data types.
Just to add to some of the other comments about not being able to return different data types in the same column... Database columns should know what datatype they are holding. If they don't then that should be a BIG red flag that you have a design problem somewhere, which almost guarantees future headaches (like this one).