SQL encryption only returning first character - c#

I have the following query
UPDATE mytable
SET col1 = ENCRYPTBYPASSPHRASE ('Key', col2)
FROM mytable
when I decrypt it using
SELECT CONVERT(VARCHAR(20), DECRYPTBYPASSPHRASE ('Key', col1))
FROM mytable
The result returned is only the first character, for example if the field contains "Computer" the result is only "C".

col2 is probably nvarchar not varchar. Try
SELECT CONVERT(NVARCHAR(20), DECRYPTBYPASSPHRASE ('Key', col1))
FROM mytable
In nvarchar the code points for standard ASCII letters are the same as for ASCII but padded out with a 0x00 byte.
When you cast that to varchar that it is treated as a null character that terminates the string.

After investigation I had come to many issues so I will post what I came across, so anyone can benefit from it.
If you changed to data type of the SQL column to varbinary then make sure that when you decrypt the data, you use the same old data type. That is if you had a column of varchar that contains data and then you changed it to varbinary, you must decrypt it using varchar, if you use nvarchar ,you will get garbage data.
You must encrypt and decrypt using the same way. That is if you are loading the password from a stored procedure and use it in encrypting,and the SAME EXACT password is loaded using a function for decryption, u will also get garbage data (I tested it but I did not know why is this behaviour!)may be internally there is some difference between how data is returned from SP and functions.
Hope this helps anyone out there !

Use CONVERT with data type and size of the value you are encrypting updating.
Looks like EncryptByKey does not recognize the data properly as per column schema.
Try as below
ENCRYPTBYKEY(KEY_GUID('<Key Name>'), CONVERT(varchar(20),col1))

Related

Not able to save more than 43679 char in text datatype column in SQL Server

I have a column in table with text datatype and trying to save some string value to this column from C# code. Issue comes when I use some very large string.
I am not able to save more than 43679 character into text field. I know text size can be 2^31.
I also tried saving same value from SSMS and noticed same scenario.
There is nothing special about code, but still SQL query is given below...
update TableName
set ColumnName = 'some text more than 43679 char'
where id=<some int id>
just to mention... column is declare in table as
[columnname] [text] NULL
Can anyone tell me what could be wrong.
You can try to use varchar(max) to store huge amount of data. See MSDN
We recommend that you store large data by using the varchar(max),
nvarchar(max), or varbinary(max) data types. To control in-row and
out-of-row behavior of these data types, use the large value types out
of row option.
You can also check the same issue here: SSMS - Can not paste more than 43679 characters from a column in Grid Mode

When I insert in the textbox arabic characters are saved as "????" [duplicate]

How can I insert Arabic characters into a SQL Server database? I tried to insert Arabic data into a table and the Arabic characters in the insert script were inserted as '??????' in the table.
I tried to directly paste the data into the table through SQL Server Management Studio and the Arabic characters was successfully and accurately inserted.
I looked around for resolutions for this problems and some threads suggested changing the datatype to nvarchar instead of varchar. I tried this as well but without any luck.
How can we insert Arabic characters into SQL Server database?
For the field to be able to store unicode characters, you have to use the type nvarchar (or other similar like ntext, nchar).
To insert the unicode characters in the database you have to send the text as unicode by using a parameter type like nvarchar / SqlDbType.NVarChar.
(For completeness: if you are creating SQL dynamically (against common advice), you put an N before a string literal to make it unicode. For example: insert into table (name) values (N'Pavan').)
Guess the solation is first turn on the field to ntext then write N with the value. For example
insert into eng(Name) values(N'حسن')
If you are trying to load data directly into the database like me, I found a great way to do so by creating a table using Excel and then export as CSV. Then I used the database browser SQLite to import the data correctly into the SQL database. You can then adjust the table properties if needed. Hope this would help.

Convert varchar to nvarchar

My company use sql server 2000 to store data . There is a table with a column named 'Vattu' .
The problem is that : this column declare as varchar data type , however it's save both unicode and anscii value !
So every time I show this column data on web , it show unreadable characters.
Is there any way to convert data to unicode value using c# ?
A quick google search would have given you the answer. Anyway you use System.Text.Encoding to encode the ascii to unicode. check the sample code at Encoding.Convert Method
Also converting the column datatype to NVarchar will be better in long run. Doing so you will save CPU processing that you will be using due to conversion at c# level.
You need to change the data type of the column to nvarchar in order to store Unicode data.
The Unicode data you've already tried to store in the column is gone - you can't magically get it back, unless your application logged the data or you were running traces of all commands and still have access to those.

Are there any benefits to using sql_variant over varchar in SQL Server?

I currently have a database table setup as follows (EAV - business reasons are valid):
Id - int (PK)
Key - unique, varchar(15)
Value - varchar(1000)
This allows me to add in mixed values into my databse as key/value pairs. For example:
1 | 'Some Text' | 'Hello World'
2 | 'Some Number' | '123456'
etc.
In my C# code I use ADO.Net using reader.GetString(2); to retrieve the value as a string, then have my code elsewhere convert it as needed, for example... Int32.ParseInt(myObj.Value);. I'm looking at enhancing my table by possibly changing the value column to a sql_variant datatype, but I don't know what the benefit of this would be? Basically, is there any advantage to having my value column be of sql_variant vs varchar(1000)?
To be more clear, I read somewhere that sql_variant gets returned as nvarchar(4000) back to the client making the call (ouch)! But, couldn't I cast it to it's type before returning it? Obviously my code would have to be adjusted to store the value as an object instead of a string value. I guess, what are the advantages/disadvantages of using sql_variant versus some other type in my current situation? Oh, and it is worth mentioning that all I plan to store are datetimes, strings, and numerical types (int, decimal, etc) in the value column; I don't plan on storing and blob or images or etc.
The good thing about sql variant is that you can store several types in a column and you keep the type information.
Insert into MySettings values ('Name','MyName'); Insert into
MySettings values ('ShouesNumber',45); Insert into MySettings values
('MyDouble',31.32);
If you want to retrieve the type:
select SQL_VARIANT_PROPERTY ( value , 'BaseType' ) as DataType,* from mysettings
and you have:
Datatype Name Value
-----------------------------
varchar Name MyName
int ShoesNumber 45
numeric MyDouble 31.32
Unfortunately this has several drawbacks:
not very fast
not well supported by ORM frameworks
If you change the type to sql_variant, you will have to use the IDataRecord.GetValue method. It will preserve the type all the way.
So in .NET it will allow you to have this kind of code:
// read an object of SQL underlying data type 'int' stored in an sql_variant column
object o = myReader.GetValue(); // o.GetType() will be System.Int32
// read an object of SQL underlying data type '(n)varchar' or '(n)char' stored in an sql_variant column
object o = myReader.GetValue(); // o.GetType() will be System.String
// read an object of SQL underlying data type 'datetime' stored in an sql_variant column
object o = myReader.GetValue(); // o.GetType() will be System.DateTime
etc...
Of course, it supposes you do the same when saving. Just set SqlParameter.Value to the opaque value, don't use the DbType.
EAV with various (standard) types as value is the one case where I personally think sql_variant is interesting.
Of course "SQLServer-focused guys" (read: DBAs) don't like it at all :-) On the SQL Server side, sql_variant is not very practical to use (as noted in the comments), but if you keep it as an opaque "thing" and don't have to use it in SQL procedure code, I think it's ok. So, it's more an advantage on the .NET/OO programming side.
The sql_variant type has its limitations as described well by Zarathos.
What I find confusing is that you mention varchar(1000) and then 'ouch' about returning a converted nvarchar(4000).
I would start by saying that it is a good thing that the entire world have finally stopped using local and limited charsets and decided to go all in on Unicode and UTF-8, so you should prefer nvarchar over varchar and ntext over text.
And the return is nvarchar(4000) and not nchar(4000). Difference is that any varchar is - variable in size, while the plain type char is fixed in size. Returning tuples of char(4000) would be sending a lot of empty waste, but with varchar this is not an issue.
Okay. But what would be a proper datatype be for you? I would recommend ntext.
What was 1000 today could be 10'000 tomorrow. If you have 'a lot of text' that you are not indexing, then perhaps your database should not decide what the limit may be. It's just text.
ntext also fits well with .NET, as its strings are always in Unicode.
Conversion from string to int is also faster in .NET than done by sql server.
Hope this helps
I don't see that it has been mentioned yet, so I'll mention that a fairly common approach to this problem is a table like this:
Id - int (PK)
Key - unique, varchar(15)
ValueType - Integer (0 - String, 1 - Integer, 3 - Float) (optional)
StringValue - varchar(1000)
IntValue - Integer
FloatValue - Double
Advantages:
Data is saved in its appropriate form (storing ints as strings wastes a lot of bits)
You can do fancy queries like WHERE left(key,5) = 'SHOES', and IntValue>5
The ValueType column is only useful you are using prefix/suffixes on your keys (to retrieve sets of keys) and the set could be of mixed type. i.e. WHERE left(key,4) = 'Size' and ValueType = 1
Disadvantages:
Everywhere where you use this table you have to ensure that you/get/set the correct Value column
If you decide you need/want the ValueType column, you have to ensure that you get/set it correctly.

MySql C# Insert Error. Incorrect string value: '\xE1ra'

I'm using the C# .NET Mysql Connector, and when running this query:
INSERT INTO convos (`userid`,`time`,`from`,`content`,`read`,`deleted`, `ip`, `source`, `charname`, `to`) VALUES ('3', '1347396787', 'Chára', '........', '0', '0', '0.0.0.0:0000', 'C', 'óóóíííí', 'óóóíííí');
I get the following error:
Incorrect string value: '\xE1ra' for column 'from' at row 1
I understand my encoding, everything was configured for utf8, utf8_general_ci. Database, table and columns are configured for utf8. The data is sent from the client in utf8.
If i use a 3rd party tool like, Workbench to insert the query or use the mysql command line it works fine. I don't know if there is a bug with the connector or i need to be doing something else with the values before insert?
Any idea?
Thanks
Is there any in mysql to covert to the correct type?
I believe you need to alter the column's char set:
use below code for those columns which is using UTF-8.
ALTER TABLE database.table MODIFY COLUMN col VARCHAR(255)
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
Unicode string prefix with N
First see your table convos and make sure columns data types is either one of nchar, nvarchar and You must precede all Unicode strings with a prefix N when you deal with Unicode string constants in SQL Server
Tyr:
insertQuery = "INSERT INTO convos (`userid`,`time`,`from`,`content`,`read`,`deleted`, `ip`, `source`, `charname`, `to`) VALUES
(N'3', N'1347396787', N'Chára', N'........', N'0', N'0', N'0.0.0.0:0000', N'C', N'óóóíííí', N'óóóíííí')";
I figured this out, its taken a while but it seems i was setting the charset too often. The database, tables, columns are all in UTF8. When i made a connection i had "CHARSET=UTF8" in the connection string. I was also running "SET NAMES 'utf8' COLLATE 'utf8_general_ci'" everytime i made a connection. I dropped the CHARSET=UTF8 and "SET NAMES 'utf8' COLLATE 'utf8_general_ci'" and its all working now.
Update it
INSERT INTO convos (`userid`,`time`,`from`,`content`,`read`,`deleted`, `ip`, `source`, `charname`, `to`) VALUES ('3', '1347396787', 'Chara', '........', '0', '0', '0.0.0.0:0000', 'C', 'óóóíííí', 'óóóíííí');
I think for "chara"in your 3rd value gives it
For someone who has tried all the suggestions, and nothing has worked (like myself), it is worth checking what MySQL types are your fields mapped to in C#. My text fields were automatically mapped as MySqlDbType.Blob and that was causing the error. I changed the type to MySqlDbType.Text, and I don't see the error any more.
Here is my original response to a similar thread:
https://stackoverflow.com/a/16989466/2199026
config mysql like below. it will solve the unicode error when insert into mysql from java or C#
enter image description here

Categories

Resources