Update Decimal valued fields in SQL Server - sql-server-2008

I want to do the following to my database:
UPDATE Addresses
SET Latitude = 1000, Longitude = 1000
WHERE Latitude IS NULL AND Longitude IS NULL
1000 is not a valid latitude or longitude. Latitude and Longitude are new columns in my database, and I don't want any of the fields to be null. I handle invalid latitude and longitude values in my application, but having them null creates difficulties.
When I try to run this query, I get the following error:
Msg 8115, Level 16, State 8, Line 3
Arithmetic overflow error converting int to data type numeric.
The statement has been terminated.
The datatypes of the Latitude and Longitude column are both Decimal(18,15). I assume that I have to write these decimal entries in a particular way, but I can't work out what it is.
Could someone enlighten me?

You are overflowing your specified parameters for the datatype.
DECIMAL(18,15) means you have 18 total places, and 15 of those are right of the decimal. This leaves 3 places left of the decimal, and 1000 is a four digit number.
You need to either change the datatype to something like DECIMAL(18,14) or use a value like 999.999999999999999.

Related

MySQL ERROR 1264 (22003): Out of range value for column

I get this error:
ERROR 1264 (22003): Out of range value for column 'median_comments' at
row 1
after running this query:
update influencers set `median_comments` = 1347 WHERE `id` = 1;
I'm not sure why this fails on this number which doesn't have any decimals and which is only 4 digits.
The field type is:
median_comments decimal(10,8)
You are using DECIMAL(10,8) that means max digits before decimal would be (10 - 8) = 2.
Reference: DECIMAL Data Type Characteristics
The declaration syntax for a DECIMAL column is DECIMAL(M,D). The ranges of values for the arguments are as follows:
M is the maximum number of digits (the precision). It has a range of 1 to 65.
D is the number of digits to the right of the decimal point (the scale). It has a range of 0 to 30 and must be no larger than M.
To fix the error, change your datatype to DECIMAL(10,2).
ALTER TABLE `influencers`
CHANGE COLUMN `median_comments` `median_comments` DECIMAL(10,2) NOT NULL DEFAULT 0;
If you are using decimal(10,8) as data type it means you are specifying 8 digits after decimal place which leaves only (10 - 8 i.e 2 digits) for your whole number.
In this case since your number 1347 contains 4 digits (whole number) hence you are getting the error as "Out of range value" since you are allowed only 2.
You should consider changing it to at least decimal (12,8) which will leave you 4 digits for your whole number part and your above command should work.
Please refer to post - Number format issue in Oracle. Same issue.
As you like me came here from google and your issue is related to Doctrine, and your column type is type="decimal", then you should configure precision and scale properties of your column in the right way.
For me, it was like before:
/** #ORM\Column(name="revenue", type="decimal", scale=4, nullable=true) */
private $revenue;
after
/** #ORM\Column(name="revenue", type="decimal", precision=14, scale=4, nullable=true) */
private $revenue;
It will be converted to DECIMAL(14,4), which means fourteen digits total, four of which are to the right of the decimal point.
Don't forget to prepare migration and run it to apply the changes.
Finally, you should get SQL like this:
ALTER TABLE project_finance CHANGE revenue revenue NUMERIC(14, 4) DEFAULT NULL

mySQL column without a one-size-fits-all precision for DECIMAL

When I define a table to store decimal values I use a statement like this:
CREATE TABLE myTable (
myKey INT NOT NULL,
myValue DECIMAL(10,2) NOT NULL,
PRIMARY KEY (myKey)
);
However, this results in every myValue being stored with a one-size-fits-all precision of (10,2). For instance
45.6 becomes 45.60
21 becomes 21.00
17.008 becomes 17.01
But what if each record has a myValue of different precision? I need 45.6 to remain 45.6, 21 to remain 21, and 17.008 to remain 17.008. Otherwise the precision of measurement is being lost. There's a big difference between 21 and 21.00.
If you don't need to do greater/less-than compares, store as a VARCHAR(..)
The strings '21' and '21.00' would have identical values, but present different "precision".
When needing the numeric value, add zero (col + 0).
This does not allow for "negative precision", such as "1.2M" being represented as 1200000. If you need that, then Norbert's approach is probably better.
You can store with high precision and exact recall by following a different way of storing the data:
Create a table with two columns:
CREATE TABLE precise (value BIGINT, decimaldot INT);
Use code to determine where the dot is, for example in your 21 value: 2 (assuming 1 indexing). So stored the value would be:
INSERT INTO precise values (21,2);
Retrieved it would return 21 exact (parsing back the dot in the value 21 at position 2, is 21)
Value 17.008 would also have decimaldot at 2:
INSERT INTO precise values (17008,2);
Etc..
Larger values can be stored by using a VARCHAR(4000) instead of a biginteger, or by using blob fields.

How do I enter an "empty" POINT() geometry value into a MySQL field of type POINT?

I have a table with a POINT geometry field. I enter latitude/longitude points into it like this:
INSERT INTO table( point )
VALUES( POINT( lon_value, lat_value );
Sometimes I do not have lat/lon values to enter. I am unable to enter a blank, a NULL, or an empty POINT() ... since POINT(0,0) is actually a location on the globe, that won't work either.
What is the solution here?
I would use coordinates of North Pole
INSERT INTO table( point )
VALUES( POINT(0.0000,90.0000);
If the actual coordinates of the pole may be an issue i would change the lon value from 0.0000.
Only GeometryCollection supports EMPTY: https://dev.mysql.com/doc/refman/8.0/en/gis-data-formats.html
INSERT INTO table( point )
VALUES( ST_GeomFromText('GEOMETRYCOLLECTION EMPTY') );
Since the valid range of latitude in degrees is -90 and +90 for the southern and northern hemisphere respectively; I'm able to switch values to and from NULL by passing in and using 99 (arbitrary out of range number) for Lat comparison like this:
("UPDATE
tableName SET LatLng = IF(%Lat = 99, NULL, POINT(%Lat, %Lng))
Where itemID = %itemID"
, array(
'itemID' => $itemID,
     'Lat' => $Lat == NULL ? 99 : $Lat,
'Lng' => $Lng == NULL ? NULL : $Lng
));

Anomalous mysql behaviour on replace query

im using a v simple database and i have 3 columns A(bigINT 20) , B(bigInt 20) and c(DECIMAL(5,4)) , when i fire the following query i get the below mentioned results :
REPLACE INTO `my_table` SET `A` = 8,`B` = 44,`C` = 14;
i get these values in mysql A =8 , b= 44 and c as 9.9999 ! ?
any ideas as to why is this happening and what can i do to resolved this ?
DECIMAL(5,4) means that the number has at most 5 digits, 4 of them after decimal point. So 14 is simply overflow as it would require DECIMAL(6,4).
It must be cleared that 14 is overflow, because as constant precision point decimal it is internally 14.0000 here (so six digits over five).
So if you try to put 14.0000 (six digits) in DECIMAL(5,4) (five digits max) -> MySQL chooses value closest to the one you request. Therefore 14.0000 gets "rounded" to 9.9999.
To fit 14 in your column you can either extend it do DECIMAL(6,4) (to allow more digits in general) or change to DECIMAL(5,3) (which will allow one more digit before decimal point, but loses some precision of course).

Retrieve coordinates from MySQL Geometry column

I just started using the MySQL Geospatial extension in hope of speeding up lat/lng range searches in my database of 500K points. A new GEOMETRY column p is created.
Problem:p & AsText(p) values returned are simply (BLOB), not in decimal degrees. No values are returned by GeomFromText(p). Because I had the redundant lat and lng columns, I still manage to get the lat lng values that I need. But I'm thinking of removing the lat and lng cols and just rely on p.
Converted existing Lat/Lng values to Points
UPDATE listings SET p = GeomFromText('POINT(39.948177 -75.174324)') WHERE listing_id = '585221';
Attempt to Retrieve Lat Lng from GEOMTRY col p
SELECT listing_id, lat, lng, GeomFromText(p), AsText(p), p from listings WHERE MBRContains( GeomFromText('Polygon((39 -76, 40 -76, 40 -74, 39 -74, 39 -76))'), p)
If you use AsText you will get your object in WKT format. To extract point coordinates use:
SELECT listing_id X(p), Y(p)
FROM listings
WHERE MBRContains( GeomFromText('Polygon((39 -76, 40 -76, 40 -74, 39 -74, 39 -76))'), p)
MySQL probably returns result of AsText as BLOB because it can get really long for complex objects. It's just that whatever you are using to display results can't cope with that, but the text is there.