I have created a table with username,password,hashvalue as columns.
create table userDetails
(
username varchar(50),
password varchar (50),
hashvalue varchar (3000)
)
I want to have each password stored in the table to be hashed by executing a stored procedure and in the same stored procedure, the hashed value is inserted into the table.
I created the stored procedure as follows :
CREATE PROCEDURE hashpwd
#username varchar(50) = default ,
#pwd varchar(50) = default
AS
BEGIN
DECLARE #hashed varchar(4000);
SET #hashed = HASHBYTES('SHA1', #pwd); --edited to #pwd
select username,password from userDetails
WHERE username LIKE #username AND password LIKE #pwd;
END
BEGIN
insert into userDetails
(hashvalue) values (#hashed);
END
The procedure can be executed, but the result is wrong. It produces NULL and a random string of characters. A 3rd row was also created when there are only 2 rows in the table initially.
Any guidance is appreciated.
Create PROCEDURE hashpwd
#username varchar(50) = default ,
#pwd varchar(50) = default
AS
BEGIN
DECLARE #hashed varchar(4000);
SET #hashed = HASHBYTES('SHA1', #pwd); --(#pwd instead of #hashed)
Update userDetails set hashvalue = #hashed
WHERE username LIKE #username AND password LIKE #pwd
END
You should use Update statement instead of Insert and statement should appear with in the procedure body.
I keep getting an error when submitting my response, but for the previous response above, replace the where clause with this
WHERE username = #username
The reason you are seeing the wrong results is due to the data type for your hashvalue column. As the HASHBYTES function returns VARBINARY, you should use this as your data type.
create table userDetails
(
username varchar(50),
password varchar (50),
hashvalue varbinary(40) -- Note, this should only be 40 characters long
)
I'm not really sure what youre stored procedure is meant to do. I would imagine that for a given username & password, you want to update the hashvalue on the corresponding row? If so, I would do this.
CREATE PROCEDURE hashpwd
#username varchar(50) = default ,
#pwd varchar(50) = default
AS
BEGIN
UPDATE userDetails
SET hashvalue = HASHBYTES('SHA1', #pwd); --edited to #pwd
WHERE username LIKE #username AND password LIKE #pwd;
END
Related
For context:
I have a windows form with a datagrid populated with data from my SQL Server database. I have 'selected' a row that I want to edit. This 'edit' form has textboxes filled with the
selected rows data. I have then changed some of the data and want the changed data to be saved to the database.
This is a stored procedure I have written in SQL Server. I want the passed in ID (which is unchangeable to the user in the windows form) to match the ID in the table. This will allow the data to be changed from here. How can I match the ID fields?
alter procedure spData_Audit
#ID int,
#Name varchar(100),
#Description varchar(3000),
#AdditionalInformation varchar(3000) = NULL
as
begin
set nocount on;
insert into dbo.Data (ID, Name, Description, AdditionalInformation)
values(#ID, #Name, #Description, #AdditionalInformation)
where #ID = ID
end
You should use an update for that. See example below:
ALTER PROCEDURE spData_Audit
#ID INT,
#Name VARCHAR(100),
#Description VARCHAR(3000),
#AdditionalInformation VARCHAR(3000) = NULL
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.Data
SET Name = #Name,
Description = #Description,
AdditionalInformation = #AdditionalInformation
WHERE ID = #ID;
END;
I have an SQL Server 2008 table with a structure similar to the following:
ID int PRIMARY KEY IDENTITY(1,1)
Name nvarchar(100)
LongText ntext
What I am trying to achieve is simple. Before inserting data inside this table, I want to encrypt the LongText using AES_192 algorithm. I am using the following SP to encrypt data:
create proc sp_Encrypt_LongText
#rawText ntext = null,
#encryptedText nvarchar(max) output
as
begin
OPEN SYMMETRIC KEY Encryption_Symmetric_Key
DECRYPTION BY CERTIFICATE Encryption_Certificate WITH PASSWORD = 'mypassword'
set #encryptedText = ENCRYPTBYKEY(KEY_GUID(N'Encryption_Symmetric_Key'), cast(#rawText as nvarchar(max)))
CLOSE SYMMETRIC KEY Encryption_Symmetric_Key
end
and for decryption, I have created the following SP:
alter proc sp_Decrypt_LongText
#encryptedText ntext = null,
#decryptedText varchar(max) output
as
begin
OPEN SYMMETRIC KEY Encryption_Symmetric_Key
DECRYPTION BY CERTIFICATE Encryption_Certificate WITH PASSWORD = 'mypassword'
set #decryptedText = cast(DECRYPTBYKEY(cast(#encryptedText as nvarchar(max))) as varchar(max))
CLOSE SYMMETRIC KEY Encryption_Symmetric_Key
end
The procedures seem to work fine when I use the exec command. So far, so good. The problem is that the data is inserted and fetched inside the table using stored procedures; one each for insert and select. What I have as of now is as follows:
For insertion:
create proc sp_InsertData
#Name nvarchar(100),
#LongText ntext = NULL
as
INSERT INTO TABLE tbl VALUES (#Name, #LongText)
For fetching
create proc sp_FindDataById
#Id int
as
SELECT ID, Name, LongText from tbl where ID=#Id
My question is, how do I plug the encryption/decryption procedures inside these SPs to make them work?. I have looked into several articles for achieving this, but I keep running into one issue or another; mostly because of the ntext datatype. Or maybe I might be going on the wrong path here. Any kind of help is appreciated.
PS: Due to some reasons specified by the DBAs, I can't change the data type of LongText from ntext to nvarchar or varchar. Hence, all the casting is applied in the procedures.
Okay, so I managed to convince the DBAs to have the data transferred to a new column with varbinary(max) data type. Then I transferred the values into this new column after encrypting them, and then dropped the older column and renamed the new one to the old one's name. Took some work, but everything is running smoothly now. I managed to create a stored procedure and two functions to further modularize the scripts.
For opening the symmetric key
CREATE PROCEDURE sp_OpenEncryptionKeys
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
OPEN SYMMETRIC KEY Encryption_Symmetric_Key
DECRYPTION BY CERTIFICATE Encryption_Certificate
END TRY
BEGIN CATCH
--catch
END CATCH
END
For encrypting:
CREATE FUNCTION Encrypt
(
#ValueToEncrypt varchar(max)
)
RETURNS varbinary(max)
AS
BEGIN
-- Declare the return variable here
DECLARE #Result varbinary(max)
SET #Result = EncryptByKey(Key_GUID('My_Encryption_Symmetric_Key'), #ValueToEncrypt)
-- Return the result of the function
RETURN #Result
END
For decrypting:
CREATE FUNCTION Decrypt
(
#ValueToDecrypt varbinary(max)
)
RETURNS varchar(max)
AS
BEGIN
-- Declare the return variable here
DECLARE #Result varchar(max)
SET #Result = DecryptByKey(#ValueToDecrypt)
-- Return the result of the function
RETURN #Result
END
For inserting
exec sp_OpenEncryptionKeys
INSERT INTO tbl VALUES ('Name', Encrypt('some text here'))
For fetching
exec sp_OpenEncryptionKeys
SELECT ID, Decrypt(LongText) from tbl
Hope this helps someone.
In my project, I am using reporting service to create report form SQL DB.
However, the error below is shown (ALL variable which of type datetime bring this error).
The value provided for the report parameter 'THE_DATE' is not
valid for its type.
I will tell you all the information I can provided to you for this question.
In report project,
I build up a field which its f(x) is =IIf
(Parameters!THE_DATE.Value Is
Nothing,Nothing,Format(Parameters!THE_DATE.Value,"yyyy-MM-dd"))
I also create a variable named THE_DATE which of type Date/Time and set Allow null value.
In the dataset, the query is
EXEC MC_GetDateReport #THE_DATE, #DEPARTMENT,
#TYPE, #ID
In the SQL:
the stored procedure is shown as below:
ALTER procedure [dbo].[MC_GetDateReport ]
#THE_DATE as datetime = null,
#DEPARTMENT as nvarchar(MAX) = null,
#TYPE as nvarchar(MAX) = null,
#LAN_ID as nvarchar(MAX) = null
AS
SET NOCOUNT ON
DECLARE
#SQLSTRING nvarchar(MAX),
#PARAMETER nvarchar(500);
SET #CASE = 0;
SELECT #SQLSTRING = N'';
Could anyone tell me why it say The 'THE_DATE' is not valid as both variable is type of datetime?
I want to store hashed passwords in my database and I have used the following code:
ALTER PROCEDURE AddUser
#name NVARCHAR(MAX),
#password NVARCHAR(MAX),
#responseMessage NVARCHAR(MAX) OUTPUT
AS
Begin
SET NOCOUNT ON
INSERT INTO [User] (Username, PasswordHashed)
VALUES (#name, HASHBYTES('SHA2_512', #password));
END
Current instance of my table has the following state (The User's password is hi):
For validating users I'm using the following code:
SELECT COUNT(*)
FROM [User]
WHERE [User].Username = 'Bamdad' AND [User].PasswordHashed = HASHBYTES('SHA2_512', 'hi');
But the result is 0. Why doesn't the latter code work?
You are specifying your password 'hi' as varchar but procedure requires an nvarchar. So the varchar gets promoted to nvarchar with an extra byte, hence the difference in encryption.
I have a stored procedure that receives 2 parameters.
#username VARCHAR(8),
#xmlShiftDays XML
I want to delete multiple rows from the database while iterating through the XML.
I have managed to do something similar for an INSERT (see below)
INSERT INTO table(username, date)
SELECT
username = #username,
CONVERT(DATETIME,shiftDate.date.value('.','VARCHAR(10)'),103)
FROM
#xmlShiftDays.nodes('/shiftDates/date') as shiftDate(date)
This will successfully insert "x" amount of rows into my table.
I now want to re-engineer the query to DELETE "x" amount of rows. If anyone knows how or could point me in the right direction I would greatly appreciate it.
An example of what I want to achieve is:
DECLARE #username VARCHAR(8)
DECLARE #xmlShiftDays XML
SET #xmlShiftDays = '<shiftDates><date>21/01/2012</date></shiftDates>'
SET #username = 'A0123456'
DELETE FROM table
WHERE username = #username
AND date = "<b>loop through the nodes in the XML string</b>"
Assuming you're using SQL Server 2008 (or newer) for this so I can use the DATE datatype (unfortunately, you didn't specify in your question which version of SQL Server you're using).....
I would strongly recommend you use a language-independent, regional-settings-independent date format in your XML - use the ISO-8601 format of YYYYMMDD for best results.
So try something like this:
DECLARE #xmlShiftDays XML
SET #xmlShiftDays = '<shiftDates><date>20120122</date><date>20120227</date></shiftDates>'
;WITH DatesToDelete AS
(
SELECT
DeletionDate = DT.value('(.)[1]', 'date')
FROM #XmlShiftDays.nodes('/shiftDates/date') AS SD(DT)
)
SELECT * FROM DatesToDelete
This should give you the two dates combined into XML string - right?
Now, you can use this to do the deletion from your table:
DECLARE #username VARCHAR(8)
DECLARE #xmlShiftDays XML
SET #xmlShiftDays = '<shiftDates><date>20120122</date><date>20120227</date></shiftDates>'
SET #username = 'A0123456'
;WITH DatesToDelete AS
(
SELECT
DeletionDate = DT.value('(.)[1]', 'date')
FROM #XmlShiftDays.nodes('/shiftDates/date') AS SD(DT)
)
DELETE FROM dbo.Table
WHERE username = #username
AND date IN (SELECT DeletionDate FROM DatesToDelete)
Does that work for you?
You can select the date from the Xml in the same way you did for the Insert:
DELETE FROM table
WHERE username = #username
AND date IN (SELECT
CONVERT(DATETIME,shiftDate.date.value('.','VARCHAR(10)'),103)
FROM
#xmlShiftDays.nodes('/shiftDates/date') as shiftDate(date))