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.
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.
So as I understand it an int in SQL Server is automatically set to a length of 4 digits. A bigint has a default length of 8. It seems these cannot be made any other length, so what do you do when you want a column that will only contain digits and you need it to be a length of 10?
I already tried float and while it will store the 10 digits it does so in scientific notation.
int takes 4 bytes (-2^31 to 2^31 - 1), and bitint takes 8 bytes (-2^64 to 2^64 - 1). They're 32-bit and 64-bit signed integers, respectively.
Please refer to the data type documentation.
Additionally, you should avoid float and real unless you really need them, as they're approximate number types. decimal or numeric are preferred for decimal values.
If you want the equivalent of an "INT(10)", then you should use decimal(10), which will support -9999999999 to 9999999999. Bear in mind that this will use more disk space than a bigint (9 bytes), and may perform differently at very large scales.
You are mixing the concept of a human readable number (the common digits) with its digital representation (bits).
INT which takes 4 Bytes (32 bit) is not at its end at "9999"... There are 4.294.967.295 different values possible with an int...
From other comments I take, that you want to store phone numbers...
Take this as a general rule: Store in numeric fields values, which you want to use in mathematical computations.
Would you ever think that a phone number +2 or a phonenumber divided by 4 does make any sense?
Anyway: Very often phonenumbers are stored with some kind of delimiters.
Put this all together and you come to the conclusion: no DECIMAL(10), no INT, no BIGINT but VARCHAR(50) :-)
Which version of sql server are you using. I am using sql server 2014. There is a datatype decimal in it. It does what you want. If it is available in your sql server try it.
I understand there are multiple questions about this on SO, but I have yet to find a definitive answer of "yes, here's how..."
So here it is again: What are the possible ways to store an unsigned integer value (32-bit value or 32-bit bitmap) into a 4-byte field in SQL Server?
Here are ideas I have seen:
1) Use a -1*2^31 offset for all values
Disadvantages: need to perform math on the values before reading/writing/aggregating.
2) Use 4 tinyint fields
Disadvantages: need to concatenate values to perform any operations
3) Use binary(4)
Disadvantages: actually uses 4 + 2 bytes of space (Edit: varbinary(4) uses 4+2, binary(4) only uses 4)
Need to work in SqlBinary or cast to/from other types
IMO, you have the correct answers to storing 2^32 positive values in 4 bytes: either a standard int and you do the math or a binary(4) which, contrary to what you have said, will only consume 4 bytes of space. (Only varbinary will incur an extra 2 bytes of storage). A series of tinyint or smallint columns would be unjustifiably cumbersome IMO.
Of course there is another solution for storing 2^32 positive values but it takes eight bytes: a bigint with a check constraint. Given how cheap storage and memory is today, IMO, this is the simplest and cheapest solution given the programmatic hoops you will have to jump through with the other solutions, however clearly you have a reason for wanting to save the extra 4 bytes on each row.
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.
In Sql Server 2005 what data type should be used to store passwords hashed by SHA-256 algorithm?
The data is hashed by the application and passed to the database
I prefer to convert the hash-Code to an Hex-String in this case a varchar(64) will do the trick or an varchar (66) if you like a "0x"-prefix. In this way it is much easier to compare manually or (re)set values you have to copy/paste from other places. e.g you lost your admin-PW and want to reset it via SQL...
varbinary(32) or binary (32).
The "Hash" attribute of the SHA256Managed class is an array of bytes, and HashSize is 256 bits, so I believe a binary(32) would be the simplest.
You could probably also put it into a varchar field using the ToBase64Transform. I'm not completely familiar with the Base64 Algorithm, but It seems like you would need probably need at least 43 characters to represent a 256 bit number in base 64. IIRC Base64 uses a couple padding characters, so I'd probably put it at varchar(50) just to be safe.
Should produce a 32-byte value (256 bits), so binary(32) ought to work.
SHA-256 has a 256 bit output
256bits = 32 Bytes
So try varbinary(32)