Error in storing values in SQL database table - sql-server

In my table, there is a column called zipcode whose datatype is int. And when I am storing a zipcode which starts with 0 (for eg. 08872), it is getting stored as 8872.
Can anybody explain me why is it happening?

An INT value is numeric - and numerically, 08872 and 8872 are identical - both represent the value 8872.
SQL Server will not store leading zeroes for numerical values. That's just the way it is.
Either store this as CHAR(5) instead, or handle the formatting (adding leading zeroes to your zip codes) on the frontend when you need to display it.

Related

Issue with datatype Money in SQL SERVER vs string

I have a spreadsheet that gets all values loaded into SQL Server. One of the fields in the spreadsheet happens to be money. Now in order for everything to be displayed correcctly - i added a field in my tbl with Money as DataType.
When i read the value from spreadsheet I pretty much store it as a String, such as this... "94259.4". When it get's inserted in sql server it looks like this "94259.4000". Is there a way for me to basically get rid of the 0's in the sql server value when I grab it from DB - because the issue I'm running across is that - even though these two values are the same - because they are both compared as Strings - it thinks that there not the same values.
I'm foreseeing another issue when the value might look like this...94,259.40 I think what might work is limiting the numbers to 2 after the period. So as long as I select the value from Server with this format 94,259.40 - I thin I should be okay.
EDIT:
For Column = 1 To 34
Select Case Column
Case 1 'Field 1
If Not ([String].IsNullOrEmpty(CStr(excel.Cells(Row, Column).Value)) Or CStr(excel.Cells(Row, Column).Value) = "") Then
strField1 = CStr(excel.Cells(Row, Column).Value)
End If
Case 2 'Field 2
' and so on
I go through each field and store the value as a string. Then I compare it against the DB and see if there is a record that has the same values. The only field in my way is the Money field.
You can use the Format() to compare strings, or even Float For example:
Declare #YourTable table (value money)
Insert Into #YourTable values
(94259.4000),
(94259.4500),
(94259.0000)
Select Original = value
,AsFloat = cast(value as float)
,Formatted = format(value,'0.####')
From #YourTable
Returns
Original AsFloat Formatted
94259.40 94259.4 94259.4
94259.45 94259.45 94259.45
94259.00 94259 94259
I should note that Format() has some great functionality, but it is NOT known for its performance
The core issue is that string data is being used to represent numeric information, hence the problems comparing "123.400" to "123.4" and getting mismatches. They should mismatch. They're strings.
The solution is to store the data in the spreadsheet in its proper form - numeric, and then select a proper format for the database - which is NOT the "Money" datatype (insert shudders and visions of vultures circling overhead). Otherwise, you are going to have an expanding kluge of conversions between types as you go back and forth between two improperly designed solutions, and finding more and more edge cases that "don't quite work," and require more special cases...and so on.

SQL Server - Text column contains number between

Can someone tell me how I code in SQL Server so that I am looking in a varchar text column to see if it contains a numerical range within the text?
For example, I'm looking for columns that contain anything between 100000 and 999999. The column may have a value like
this field contains a number `567391`
so I want to select that one, but not if it had
this field contains a number `5391`
For your given example, you can check the digits:
where col like '%[^0-9][1-9][0-9][0-9][0-9][0-9][0-9][^0-9]%'
This is not a generic solution, but it works for your example. In general, parsing strings in SQL Server is difficult. It is better to extract the values you are interested in when loading the data, so the relevant values are correctly in their own columns.

Unable to return query Thai data

I have a table with columns that contain both thai and english text data. NVARCHAR(255).
In SSMS I can query the table and return all the rows easy enough. But if I then query specifically for one of the Thai results it returns no rows.
SELECT TOP 1000 [Province]
,[District]
,[SubDistrict]
,[Branch ]
FROM [THDocuworldRego].[dbo].[allDistricsBranches]
Returns
Province District SubDistrict Branch
อุตรดิตถ์ ลับแล ศรีพนมมาศ Northern
Bangkok Khlong Toei Khlong Tan SSS1
But this query:
SELECT [Province]
,[District]
,[SubDistrict]
,[Branch ]
FROM [THDocuworldRego].[dbo].[allDistricsBranches]
where [Province] LIKE 'อุตรดิตถ์'
Returns no rows.
What do I need o do to get the expected results.
The collation set is Latin1_General_CI_AS.
The data is displayed and inserted with no errors just can't search.
Two problems:
The string being passed into the LIKE clause is VARCHAR due to not being prefixed with a capital "N". For example:
SELECT 'อุตรดิตถ์' AS [VARCHAR], N'อุตรดิตถ์' AS [NVARCHAR]
-- ????????? อุตรดิตถ
What is happening here is that when SQL Server is parsing the query batch, it needs to determine the exact type and value of all literals / constants. So it figures out that 12 is an INT and 12.0 is a NUMERIC, etc. It knows that N'ดิ' is NVARCHAR, which is an all-inclusive character set, so it takes the value as is. BUT, as noted before, 'ดิ' is VARCHAR, which is an 8-bit encoding, which means that the character set is controlled by a Code Page. For string literals and variables / parameters, the Code Page used for VARCHAR data is the Database's default Collation. If there are characters in the string that are not available on the Code Page used by the Database's default Collation, they are either converted to a "best fit" mapping, if such a mapping exists, else they become the default replacement character: ?.
Technically speaking, since the Database's default Collation controls string literals (and variables), and since there is a Code Page for "Thai" (available in Windows Collations), then it would be possible to have a VARCHAR string containing Thai characters (meaning: 'ดิ', without the "N" prefix, would work). But that would require changing the Database's default Collation, and that is A LOT more work than simply prefixing the string literal with "N".
For an in-depth look at this behavior, please see my two-part series:
Which Collation is Used to Convert NVARCHAR to VARCHAR in a WHERE Condition? (Part A of 2: “Duck”)
Which Collation is Used to Convert NVARCHAR to VARCHAR in a WHERE Condition? (Part B of 2: “Rabbit”)
You need to add the wildcard characters to both ends:
N'%อุตรดิตถ์%'
The end result will look like:
WHERE [Province] LIKE N'%อุตรดิตถ์%'
EDIT:
I just edited the question to format the "results" to be more readable. It now appears that the following might also work (since no wildcards are being used in the LIKE predicate in the question):
WHERE [Province] = N'อุตรดิตถ์'
EDIT 2:
A string (i.e. something inside of single-quotes) is VARCHAR if there is no "N" prefixed to the string literal. It doesn't matter what the destination datatype is (e.g. an NVARCHAR(255) column). The issue here is the datatype of the source data, and that source is a string literal. And unlike a string in .NET, SQL Server handles 'string' as an 8-bit encoding (VARCHAR; ASCII values 0 - 127 same across all Code Pages, Extended ASCII values 128 - 255 determined by the Code Page, and potentially 2-byte sequences for Double-Byte Character Sets) and N'string' as UTF-16 Little Endian (NVARCHAR; Unicode character set, 2-byte sequences for BMP characters 0 - 65535, two 2-byte sequences for Code Points above 65535). Using 'string' is the same as passing in a VARCHAR variable. For example:
DECLARE #ASCII VARCHAR(20);
SET #ASCII = N'อุตรดิตถ์';
SELECT #ASCII AS [ImplicitlyConverted]
-- ?????????
Could be a number of things!
Fist of print out the value of the column and your query string in hex.
SELECT convert(varbinary(20)Province) as stored convert(varbinary(20),'อุตรดิตถ์') as query from allDistricsBranches;
This should give you some insight to the problem. I think the most likely cause is the ั, ิ, characters being typed in the wrong sequence. They are displayed as part of the main letter but are stored internally as separate characters.

please help me to store integer value with 0 as perfix in SQL Server

I have a column with bigint datatype in SQL Server 2005.
I want to store 0347 in that.. (0 should not be removed) means their must be at least four value like: 0034 , 0007, 0423,4445.
SQL will not store the 0 if you use a bigint.
You could use
select right('00000000'+ltrim(Str(<bigIntField>)),4) as DisplayVal
Change the '4' to what size you want to zero fill the fields to.
You can't store a formatted value like that in an integer field. You'd need to store as a VARCHAR.
Unless you have a very good reason, I'd keep it as you have it in the DB, but just format the number for display in the UI.
As far as I know, you can't store formatted data in an integer type field.
Run sprintf or similar over the data when you get it out of the database instead.

How are NULLs stored in a database?

I'm curious to know how NULLs are stored into a database ?
It surely depends on the database server but I would like to have an general idea about it.
First try:
Suppose that the server put a undefined value (could be anything) into the field for a NULL value.
Could you be very lucky and retrieve the NULL value with
...WHERE field = 'the undefined value (remember, could be anything...)'
Second try:
Does the server have a flag or any meta-data somewhere to indicate this field is NULL ?
Then the server must read this meta data to verify the field.
If the meta-data indicates a NULL value and if the query doesn't have "field IS NULL",
then the record is ignored.
It seems too easy...
MySql uses the second method. It stores an array of bits (one per column) with the data for each row to indicate which columns are null and then leaves the data for that field blank. I'm pretty sure this is true for all other databases as well.
The problem with the first method is, are you sure that whatever value you select for your data won't show up as valid data? For some values (like dates, or floating point numbers) this is true. For others (like integers) this is false.
On PostgreSQL, it uses an optional bitmap with one bit per column (0 is null, 1 is not null). If the bitmap is not present, all columns are not null.
This is completely separate from the storage of the data itself, but is on the same page as the row (so both the row and the bitmap are read together).
References:
http://www.postgresql.org/docs/8.3/interactive/storage-page-layout.html
The server typically uses meta information rather than a magic value. So there's a bit off someplace that specifies whether the field is null.
-Adam
IBM Informix Dynamic Server uses special values to indicate nulls. For example, the valid range of values for a SMALLINT (16-bit, signed) is -32767..+32767. The other value, -32768, is reserved to indicate NULL. Similarly for INTEGER (4-byte, signed) and BIGINT (8-byte, signed). For other types, it uses other special representations (for example, all bits 1 for SQL FLOAT and SMALLFLOAT - aka C double and float, respectively). This means that it doesn't have to use extra space.
IBM DB2 for Linux, Unix, Windows uses extra bytes to store the null indicators; AFAIK, it uses a separate byte for each nullable field, but I could be wrong on that detail.
So, as was pointed out, the mechanisms differ depending on the DBMS.
The problem with special values to indicate NULL is that sooner or later that special value will be inserted. For example, it will be inserted into a table specifying the special NULL indicators for different database servers
| DBServer | SpecialValue |
+--------------+--------------+
| 'Oracle' | 'Glyph' |
| 'SQL Server' | 'Redmond' |
;-)

Resources