I'm working on an application that uses a third-party component, and this component returns a value that is of type UInt32.
I need to store this UInt32 in a Sql Server table. I was thinking about just use a simple int column and insert the value like this:
int value = (int)(cs - int.MaxValue);
But I'm not sure if this is the best way for such task.
Use a bigint or decimal(10,0) column and defined a check constraint to ensure it's between 0 and 4 billion.
Defines a CLR datatype
I suggest you store it in a bigint column.
You should probably take + int.MinValue. As max is 2147483647 and min is -2147483648 for 32 bit signed integer. The zero steals one value from the positive side.
Related
I am using ASP.NET MVC and SQL Server and I want to store a 12 digit value which is 221133556677.
This is where I wanted to store the value in, So Int36 can only store up to 10 digit.
So how can I change the data type into numeric(12,0) in order to store the 12 digit value.
[Display(Name = "IC")]
[Required(AllowEmptyStrings = false, ErrorMessage = "IC is required")]
public int IC { get; set; }
So Int36 can only store up to 10 digit.
In all computers in the world htat follow standard architecture, there IS NO SUCH THING AS INT36. Bytes are 8 bits, so it is 32. Not 36.
And since ages, Int64 is a thing too. Which has MUCH MUCH larger scale.
In SQL Server it is named BIGINT and has a scale that may surprise you:
2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807)
Case closed?
Oh, no....
So how can I change the data type into numeric(12,0) in order to store the 12 digit
value.
Just Do It? Let's start with your C# side code using int - not long. Int is 32 bit (not 26). Just change it to - oh, you insist on using numeric (decimal)? Ah, use Decimal not int. Done. Otherwise I would go with a long and bigint on the database.
Note, though, that this "number" is likely NOT A NUMBER. It is a numeric string. Storing it as number makes little sense if you may need one day to do partial searches and never will use stuff like average, sum etc.
Now, you may want to read some documentation:
https://learn.microsoft.com/en-us/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql?view=sql-server-ver15
has all SQL Server data types. This helps you not to ignore the obvious larger scale data type.
According to the SQL Server documentation you can use BIGINT.
Its a signed 64 bit int and has a range of -2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807).
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-data-type-mappings
From what I have been able to find specifying the size of the numeric doesn't effect the size of the number it can store in SQL Server and only affects when ZEROFILL is used
What is the size of column of int(11) in mysql in bytes?
A long can store 12 digits just fine. So use long instead of int in your C#.
long twelveDigits = 221133556677;
Console.WriteLine($"\nHere is twelve digit number, {twelveDigits}.");
Console.Write("\nPress any key to exit...");
Console.ReadKey(true);
See here: Long data type MSDocs
And SQLServer has the Data Type bigint
See here: int, bigint, smallint, and tinyint (Transact-SQL)
and: www.sqlservertutorial.net
These should get you taken care of.
In my C# program I don't want to work with byte array, therefore I cast rowversion data type to bigint:
SELECT CAST([version] AS BIGINT) FROM [dbo].[mytable]
So I receive a number instead of byte array. Is this conversion always successful and are there any possible problems with it? If so, in which data type should I cast rowversion instead?
rowversion and bigint both take 8 bytes so casting seems possible. However, the difference is that bigint is a signed integer, while rowversion is not.
This is a max value of rowversion that will cast properly to max positive bigint number (9223372036854775807):
select cast(0x7FFFFFFFFFFFFFFF as bigint)
But starting from here, you'll be getting negative numbers:
select cast(0x8000000000000000 as bigint)
I didn't check if the latter cast throws an error in C#.
You problably won't reach more than 9223372036854775807 rows in your table, but still it's something you should know about, and I personally wouldn't recommend doing this unless you are certain that this problem will never occur in your solution.
You can convert in C# also, but if you want to compare them you should be aware that rowversion is apparently stored big-endian, so you need to do something like:
byte[] timestampByteArray = ... // from datareader/linq2sql etc...
var timestampInt = BitConverter.ToInt64(timestampByteArray, 0);
timestampInt = IPAddress.NetworkToHostOrder(timestampInt);
It'd probably be more correct to convert it as ToUInt64, but then you'd have to write your own endian conversion as there's no overload on NetworkToHostOrder that takes uint64. Or just borrow one from Jon Skeet (search page for 'endian').
I have a table with IDs and locales. The same ID can be listed more than once with a different locale:
ID Locale
123456 EN_US
234567 EN_US
234567 EN_CA
345678 EN_US
I need to create an unique identifier in the form of an numeric ID (Integer) for each record, while maintaining the ability to reverse engineer the original components.
I was thinking bit shifting might work: assign a numerical value to each locale, but I'm not quite sure how to implement. Has anyone faced this challenge before? Also, I have 75 locales so I'm not sure if that would be an issue with bit shifting.
Lastly, I'm using SQL Server with a Linked Server connection to Teradata (that's my data source). I don't think Teradata supports bitwise out-of-the-box so I'm assuming I'll have to do it in MSSQL.
Thank you.
You can create a composite numeric key, mapping your 75 unique values into the last 2 digits of the numeric key. You can parse into components with simple modulus 100 arithmetic or just a substring. If you will ever exceed 100 values, use 3 digits instead. 9 digits total will fit int an int, 10-18 will fit in a bigint.
Converting 234567-EN_US into an integer is easy. Just use CHECKSUM on the concatenated string value. It would not be reversible, however.
You could store this CHECKSUM value on the original table, however, and then use it to backtrack from whatever table you're going to store the integer in.
Another solution would be to assign each locale an Integer value (as Marc B suggested). Call that X. Then call your existing integer ID (234567) as Y. Your final key would be (X * 1,000,000) + Y. You could then reverse the formula to get the values back. This would only work, of course, if your existing integer IDs are well below 1,000,000, and also if your final integer can be a BigInt.
I've got a question about storing bitwise flags in sql. I have a number of status flags which i'd like to store in a SQL smallint field. So a smallint can represent -32768 to 32767.
If I want to use all 32 bits to store boolean values how do I reference the bits. For instance. If I want to store bits that make up the number 1 i would normally see 31 zeros and a 1 in the LSB. Would would that sequence equate to as a value in my smallint field? What about 1 in the MSB and zero in all other bits? Maybe there is a better way to store and query bitwise data in SQL.
Thanks in advance.
Use the bit datatype? One per flag you need
SQL Server packs bit columns into as many bytes as needed
upto 8 = 1 byte
9-16 is 2 bytes
...
The DB engine will also take care of all bit masks etc for you
All you see are discrete bit values
So... why roll your own?
The ideal solution would be to use 32 separate TinyInt fields. TinyInt supports values 0-255. If you try to use a single field and do bit processing you lose the ability to index any of these flags just as you would if you used Bit type fields.
What is the best way to store an ID card number (8 digits) in a database? Integer or VARCHAR(8)? Thanks. I am using PostgreSQL.
I will assume MySQL for this question, as you failed to state any details.
Since it's a numeric value, not a string, I recommend using a numeric type. You can make the best use of space by using the narrowest type that's wide enough in MySQL, which is DECIMAL(8).
Also make the column UNSIGNED, and possibly use ZEROFILL.
Unsigned Integer should be large enough to handle 99999999 since it's max value is 4294967295. Integer should also be faster when searching and will also be a smaller storage data type.