PD:Some names are in Spanish, sorry.
I have a table containing columns Usuario and Contraseña.
For each one it will be necessary to determine: login user (unique in the system and identification) and access password (which must contain 5 letters and 2 numbers - exact length 7). Consider that the login name must have exactly 10 characters
The table created is as follows:
CREATE TABLE Empleado
(
Usuario varchar(10) NOT NULL UNIQUE
CHECK(LEN([Usuario]) = 10),
Contraseña varchar(7) NOT NULL
CHECK (LEN([Contraseña]) = (7) AND [Contraseña] LIKE '%[0-9]%' AND [Contraseña] LIKE '%[A-Z]%')
)
And the data is inserted like this:
INSERT INTO Empleado (Usuario, Contraseña)
VALUES ('santiago21', 'qwerty1')
INSERT INTO Empleado (Usuario, Contraseña)
VALUES ('FaaacuuUwU', 'qwertY1')
The problem is that the second insert should take it, but the first one should not, which it DOES NOT DO.
Does anyone know how I should do it? Thank you.
We can take advantage of SQL Server's enhanced LIKE operator here:
CREATE TABLE Empleado (
Usuario varchar(10) NOT NULL UNIQUE CHECK(LEN([Usuario]) = 10),
Contraseña varchar(7) NOT NULL CHECK (
LEN([Contraseña]) = 7 AND
[Contraseña] LIKE '%[0-9]%[0-9]%' AND -- 2 numbers
[Contraseña] LIKE '%[A-Za-z]%[A-Za-z]%[A-Za-z]%[A-Za-z]%[A-Za-z]%') -- 5 letters
)
);
Edit:
In general you should not be storing clear text passwords in your database. The reason for this is that should anyone (internal or external) gain access to your Empleado table, they would get access to every credential in your entire system.
Instead, a much safer approach would be to first irreversibly hash every password and then store the hash. Then, in the unlikely event that someone undesirable might gain access to your table, they wouldn't get passwords, just usernames with some gibberish password hashes that they couldn't easily back out to the original passwords.
Related
I would like to update table called people from:
to
Could you please help?
You need to parse out the beginning of the email address to add it to the domain name. Do that by finding the CHARINDEX of the # symbol, then subtracting one. Use that value as the length parameter in a LEFT function call.
Once you have the name from the email address, CONCATenate it to the static value of your domainname\.
I included a WHERE clause that you may want to use if you have a large number of rows where the Username is already correct and you don't want to waste a bunch of writes replacing a string with a duplicate of that same string. You could leave the WHERE off if you prefer.
UPDATE People
SET Username = CONCAT('domainname\',LEFT([E-mailAddress],CHARINDEX('#',[E-mailAddress])-1))
WHERE
Username <> CONCAT('domainname\',LEFT([E-mailAddress],CHARINDEX('#',[E-mailAddress])-1));
If you are working on earlier versions (cause CONCAT() is for 2012+ versions) and also if you have NULLs in the UserName column, you can do like
CREATE TABLE T(
[E-MailAddress] VARCHAR(50),
UserName VARCHAR(45)
);
INSERT INTO T VALUES
('abc#domainname.com', 'abc'),
('zxc#fhlbdm.com', NULL),
('MNO#domainname.com', 'MNO'),
('pqr#domainname.com', 'pq'),
('tyu#domainname.com', 'domainname\tyu');
UPDATE T
SET UserName = 'domainname\' + LEFT([E-MailAddress], CHARINDEX('#', [E-MailAddress])-1)
WHERE 'domainname\' + LEFT([E-MailAddress] , CHARINDEX('#', [E-MailAddress])-1) <> UserName
OR
UserName IS NULL;
SELECT *
FROM T;
Google (and maybe others) treat foo.bar#gmail.com and foobar#gmail.com as the same mail box.
Suppose I have a user email in my db:
foo.bar#gmail.com
And I want to check that a new user that tries to register with foobar#gmail.com will not be able to register since that email already exists.
The scenario could be the other way around where a user already registered with foobar#gmail.com and a new one tries to register with foo.bar#gmail.com. for my purposes the emails are equal, and must be "unique".
I have tried
declare #email nvarchar(255);
set #newEmail = 'foobar#gmail.com' -- or 'foo.bar#gmail.com'
select * from Users where REPLACE(Users.Email, '.', '') = REPLACE(#newEmail, '.', '')
but this seems not so efficient and might conflict with the domain part (gmail.com).
Is there a better way to do this?
I would use a computed column to remove any dots from the gmail addresses and then create a unique key on that column.
For example:
DECLARE #Test TABLE (
Email VARCHAR(50) PRIMARY KEY,
ShortEmail AS CONVERT(VARCHAR(50),CASE
WHEN Email LIKE '%#gmail.com' OR Email LIKE '%#googlemail.com'
THEN REPLACE(LEFT(Email,CHARINDEX('#',Email)),'.','')+SUBSTRING(Email,CHARINDEX('#',Email)+1,LEN(Email))
ELSE Email
END) UNIQUE
)
INSERT INTO #Test (Email) VALUES ('a.b#gmail.com'),('a.b#c.com'),('ab#c.com'),('ab.c#gmail.com'),('abc#gmail.com')
I don't understand I already define size of character as VARCHAR(30) and I try to insert data via web page = STIFF COMP,R FR DOOR SKIN CTR
but it can't
Error string or binary data would be truncated
If you create your column correctly, then it should work well
Let's see the simple example below:
CREATE TABLE [dbo].[Table_1](
[stringTest] [varchar](30) NULL
) ON [PRIMARY]
GO
Just a simple Table_1 with 1 row [stringTest] type [varchar](30)
Then I insert your string insert into Table_1(stringTest) values('STIFF COMP,R FR DOOR SKIN CTR')
It's working fine, so just a confirm: - your original text is fitted.
So other concern is:
You set up database wrongly (check my above simple table)
You use an application (asp.net per-harp) to add the value in. So you may check in debug mode to see the correct value (may be it's formatted or encoded, since i saw a comma , in your string)
I have a requirement to pull data in a specific format and I'm struggling slightly with the ROWTOCOL function and was hoping a fresh pair of eyes might be able to help.
I'm using 10g Oracle DB (10.2) so LISTAGG which appears to do what I need to achieve is not an option.
I need to aggregate a number of usernames into a string delimited with a '$' but I also need to concatenate another column to to build up email addresses.
select
rowtocol('select username_id from username where user_id = '||s.user_id|| 'order by USERNAME_ID asc','#'||d.domain_name||'$')
from username s, domain d
where s.user_id = d.user_id
(I've simplified the query specific to just this function as the actual query is quite large and all works except for this particular function.)
in the DOMAIN Table I have a number of domains such as 'hotmail.com','gmail.com' etc
I need to concatenate the username, an '#' symbol followed by the domain and all delimited with a '$'
such as ......
joe.bloggs#gmail.com$joeblogs#gmail.com$joe_bloggs#gmail.com
I've battled with this and I've got close but in reverse?!.....
gmail.com$joe.bloggs#gmail.com$joeblogs#gmail.com$joe_bloggs
I've also noticed that if I play around with the delimiter (,'#'||d.domain_name||'$') it has a tendency to drop off the first character as can be seen above the preceding '#' has been dropped from the first email address.
Can anyone offer any suggestions as to how to get this working?
Many Thanks in advance!
Assuming you're using the rowtocol function from OTN, and have tables something like:
create table username (user_id number, username_id varchar2(20));
create table domain (user_id number, domain_name varchar2(20));
insert into username values (1, 'joe.bloggs');
insert into username values (1, 'joebloggs');
insert into username values (1, 'joe_bloggs');
insert into domain values (1, 'gmail.com');
Then your original query gets three rows back:
gmail.com$joe.bloggs
gmail.com$joe_bloggs#gmail.com$joebloggs
gmail.com$joe_bloggs#gmail.com$joebloggs
You're passing the data from each of your user IDs to a separate call to rowtocol, which isn't really what you want. You can get the result I think you're after by reversing it; pass the main query that joins the two tables as the select argument to the function, and have that passed query do the username/domain concatenation - that is a separate step to the string aggregation:
select
rowtocol('select s.username_id || ''#'' || d.domain_name from username s join domain d on d.user_id = s.user_id', '$')
from dual;
which gets a single result:
joe.bloggs#gmail.com$joe_bloggs#gmail.com$joebloggs#gmail.com
Whether that fits into your larger query, which you haven't shown, is a separate question. You might need to correlate it with the rest of your query.
There are other ways to string aggregation in Oracle, but this function is one way, and you already have it installed. I'd look at alternatives though, such as ThomasG's answer, which make it a bit clearer what's going on I think.
As Alex told you in comments, this ROWTOCOL isn't a standard function so if you don't show its code, there's nothing we can do to fix it.
However you can accomplish what you want in Oracle 10 using the XMLAGG built-in function.
try this :
SELECT
rtrim (xmlagg (xmlelement (e, s.user_id || '#' || d.domain_name || '$')).extract ('//text()'), '$') whatever
FROM username s
INNER JOIN domain d ON s.user_id = d.user_id
I want to do something like SO does with DisplayName. When someone does not enter a DisplayName, I want to default this to 'User' + UserId. So the first user who signs up would get User1 - since UserId will be 1, the second User2 - since UserId will be 2, and so on.
The easiest way I can think of doing this is using a trigger, but I don't like triggers. I could save the user, then update the user after the save (basically a trigger, but done in my code). Any other ideas on how I can handle this? Is there a way I can set the default value on the column in the database?
I am using Asp.Net MVC 2, C# 4, EF4, and SQL Server 2008.
Select Coalesce(DisplayName, 'User' + Cast(UserID as varchar)) as UserName
You can set the user name in the stored procedure. if a user name has been passed to stored procedure, simply save it. otherwise, get the primary key id of the last entered user and add 1 to it. format it to whatever you like (e.g. User + newID) and save this as the new user's user name.
You can have a computedColumn
[UserName] AS ('User' + CAST(UserID AS VARCHAR)) PERSISTED
I would be inclined to generate it before saving to the database. No input = make one up.
I also would not have user User1, User2, ... but user+random: user6238945, user9287561, user8934678, etc
If you use 1, 2, 3, 4 etc then you are exposing an internal sequence. If someone gets "user4" then I know other users 1 to 3 exist, as well as number 5. This exposure was used many years by AOL or Compuserve (?) for phishing attacks.