Tinyint not as Boolean - scalikejdbc

I have an existing mysql database which I want to query with scalikejdbc.
The database uses a nullable tinyint for small values in the range [-1,3].
How can I query this value? The only way that seems to work is treating it as a boolean which does not reflect all the values.
sql"SELECT * FROM table"
.map(rs => rs.nullableBoolean("value"))).list().apply
If I try to treat it as byte or int or I get a Runtime Exception
[ResultSetExtractorException: Failed to retrieve value because For input string: "true". If you're using SQLInterpolation, you may mistake u.id for u.resultName.id.]

Related

Fetching SAP table data throws Error 8114

I'm trying to update SQL data from SAP data (same happens with insert). I'm always getting runtime error
SQL error 8114
The reason for the exception is:
Database error text: "Error converting data type nvarchar to numeric."
All fields of 'gs_sap_table2' are type CHAR100. I've tried many things like converting some fields of my structure from CHAR 100 to decimal 18,5 and fill all the 'NOT NULL' SQL fields with values but problem remains.
I'm posting you my ABAP code and a picture of the SQL database fields:
EXEC SQL.
CONNECT TO :gv_connection
ENDEXEC.
EXEC SQL.
UPDATE STOCKKEEPINGUNITS
SET ProductId = :GS_SAP_TABLE2-PRODUCTID,
CreatedOn = :GS_SAP_TABLE2-CREATEDON,
UpdatedOn = :GS_SAP_TABLE2-UPDATEDON,
UPC = :GS_SAP_TABLE2-UPC,
AvailabilityType = :GS_SAP_TABLE2-AVAILABILITYTYPE,
Stock = :GS_SAP_TABLE2-STOCK,
Currency = :GS_SAP_TABLE2-CURRENCY,
TaxClass = :GS_SAP_TABLE2-TAXCLASS,
RetailCurrentPrice = :GS_SAP_TABLE2-RETAILCURRPRICE,
Weight = :GS_SAP_TABLE2-WEIGHT,
MeasurementUnitId = :GS_SAP_TABLE2-MEASUREMENTUID,
NameL1 = :GS_SAP_TABLE2-NAMEL1,
NameL2 = :GS_SAP_TABLE2-NAMEL2,
ShippingCost = :GS_SAP_TABLE2-SHIPPINGCOST
WHERE SKUId = :GS_SAP_TABLE2-SKUID
ENDEXEC.
EXEC SQL.
COMMIT
ENDEXEC.
EXEC SQL.
DISCONNECT :gv_connection
ENDEXEC.
The error tells you that there is an nvarchar value and it is being attempted to be implicitly converted into a numeric type. So, the error happens either in the SET or the WHERE clause. Since in the WHERE clause from the two operands one is the field, SKUId, which is a varchar and not an nvarchar nor a numeric type, it is clear that the error happens somewhere in the SET clause.
In the SET clause you assign values to fields. Conversion from nvarchar to numeric happens in these assignments if and only if the right-hand-side (i.e. the value) is nvarchar and the left-hand-side (i.e. the field) is numeric.
So, in order to fix your issue, you will need to
create a list for yourself containing all numeric fields in the SET clause that receive some value
make sure that the value (right-hand-side) of the assignment operation for each field is converted into a numeric value of the exact type your field expects

SQL import via RODBC - wrong values after implicit? typecast

I have a column in an SQL table which contains 15 digit IDs stored as nvarchar (255) in MSSQL (e.g. '30000005000008498').
If I run an sql query on this using the robdc library the data is implictly casted to numeric.
library("RODBC")
odbcChannel <- odbcConnect("TableName")
ID <- sqlQuery(odbcChannel, "SELECT DISTINCT [ID] FROM TEST4")
I have verified this via
str(ID)
Next thing I have tried is to cast the data to a character using
ID <- as.character(ID)
This works without getting an error message. Unfortunately, parts of the data is altered which is kind of bad for a unique ID:
Minimum Example:
a = 30000005000008498
b <- as.character(a)
output is:
[1] "30000005000008496"
I think it might have something to do with the maximum size of numeric. For smaller numbers, as.character works just fine. However, I could not figure out how to keep the initial ID when importing from SQL.
Question1: Is there any possibility to avoid the implicit typcast to num?
Question2: Any ideas how i can import the 15 digit character string from SQL without R changing it?
Use as.is = TRUE.
testid <- sqlQuery(database,"SELECT CAST(id as CHAR) as id from my_table", as.is=TRUE);
Even if the column id numeric in the database, testid will be a data frame containing character inputs.
I think that as.is can be set for each column separately (using as.is = c(..)) or for all at the same time.
Probably the CAST(.. as CHAR) is not necessary when the column already is of type VARCHAR.

SQL Server Nullable Column

I have a SQL Server table with a few columns of type varchar which are nullable. When an aspx page posts data if the textbox is empty, the database table column is updated to an empty string.
To maintain the null value rather han have it replaced by an empty string, I can either have the logic to change the empty string to System.DBnull in the middle tier c# code or do so in the stored procedure.
Are there other better ways to handle this situation?
you can use a trigger or do it in the proc, you can use the NULLIF function
Example
DECLARE #d VARCHAR(20)
SELECT #d = ''
SELECT NULLIF(#d,'')
I would probably put it near the code that makes a decision based on the distinction between an empty string and a null string. If there is no difference between their meaning or the resulting behavior of the application, I would suggest making the field non-nullable and sticking with an empty string.

Encountering SQL Error not having to do with my query... what can I do to get to my data?

I'm trying to run this query:
select * from activity where id = 9348927
And I receive this error:
Conversion failed when converting the varchar value '04 30' to data type int.
Note that I still receive this error when I change * to id, which doesn't make any sense to me. I don't receive the error when I run this:
select top 32 * from activity where id = 9348927
I'm pretty sure this means that some of the data on the 33rd row is in a format that SQL Server doesn't like. Is there any way I can get it to ignore the error and display my data anyway?
EDIT: id is varchar(10)
This usually means that the id column is not a number datatype, but varchar.
9348927 is a number (int) and datatype precedence means the the string value '04 30' is converted to int. Standard SQL behaviour.
Try this:
select * from activity where id = '9348927'
Incidently, the implicit conversion means any index on id will not be used. Compare query plans.
The best way to "work around" this is to fix your data and column type. Otherwise, do the comparison as string which is what id most likely is.

Is there a Boolean data type in Microsoft SQL Server like there is in MySQL? [duplicate]

This question already has answers here:
How to create a yes/no boolean field in SQL server?
(12 answers)
Closed 2 years ago.
Is there a Boolean data type in Microsoft SQL Server like there is in MySQL?
If not, what is the alternative in MS SQL Server?
You could use the BIT datatype to represent boolean data. A BIT field's value is either 1, 0, or null.
You may want to use the BIT data type, probably setting is as NOT NULL:
Quoting the MSDN article:
bit (Transact-SQL)
An integer data type that can take a value of 1, 0, or NULL.
The SQL Server Database Engine optimizes storage of bit columns. If there are 8 or less bit columns in a table, the columns are stored as 1 byte. If there are from 9 up to 16 bit columns, the columns are stored as 2 bytes, and so on.
The string values TRUE and FALSE can be converted to bit values: TRUE is converted to 1 and FALSE is converted to 0.
You are looking for a bit. It stores 1 or 0 (or NULL).
Alternatively, you could use the strings 'true' and 'false' in place of 1 or 0, like so-
declare #b1 bit = 'false'
print #b1 --prints 0
declare #b2 bit = 'true'
print #b2 --prints 1
Also, any non 0 value (either positive or negative) evaluates to (or converts to in some cases) a 1.
declare #i int = -42
print cast(#i as bit) --will print 1, because #i is not 0
Note that SQL Server uses three valued logic (true, false, and NULL), since NULL is a possible value of the bit data type. Here are the relevant truth tables -
More information on three valued logic-
Example of three valued logic in SQL Server
http://www.firstsql.com/idefend3.htm
https://www.simple-talk.com/sql/learn-sql-server/sql-and-the-snare-of-three-valued-logic/
There is boolean data type in SQL Server. Its values can be TRUE, FALSE or UNKNOWN. However, the boolean data type is only the result of a boolean expression containing some combination of comparison operators (e.g. =, <>, <, >=) or logical operators (e.g. AND, OR, IN, EXISTS). Boolean expressions are only allowed in a handful of places including the WHERE clause, HAVING clause, the WHEN clause of a CASE expression or the predicate of an IF or WHILE flow control statement.
For all other usages, including the data type of a column in a table, boolean is not allowed. For those other usages, the BIT data type is preferred. It behaves like a narrowed-down INTEGER which allows only the values 0, 1 and NULL, unless further restricted with a NOT NULL column constraint or a CHECK constraint.
To use a BIT column in a boolean expression it needs to be compared using a comparison operator such as =, <> or IS NULL. e.g.
SELECT
a.answer_body
FROM answers AS a
WHERE a.is_accepted = 0;
From a formatting perspective, a bit value is typically displayed as 0 or 1 in client software. When a more user-friendly format is required, and it can't be handled at an application tier in front of the database, it can be converted "just-in-time" using a CASE expression e.g.
SELECT
a.answer_body,
CASE a.is_accepted WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS is_accepted
FROM answers AS a;
Storing boolean values as a character data type like char(1) or varchar(5) is also possible, but that is much less clear, has more storage/network overhead, and requires CHECK constraints on each column to restrict illegal values.
For reference, the schema of answers table would be similar to:
CREATE TABLE answers (
...,
answer_body nvarchar(MAX) NOT NULL,
is_accepted bit NOT NULL DEFAULT (0)
);
You can use Bit DataType in SQL Server to store boolean data.
SQL Server uses the Bit datatype
Use the Bit datatype. It has values 1 and 0 when dealing with it in native T-SQL
Use the BIT datatype to represent boolean data. A BIT field's value is either 1,0 or NULL.
create table <tablename> (
<columnName> bit
)
Unless you want a threeway boolean you should add NOT NULL DEFAULT 0 like so:
create table <tablename> (
<columnName> bit not null default 0
)
I use TINYINT(1)datatype in order to store boolean values in SQL Server though BIT is very effective

Resources