How to update the SQL Server table based on different column value - sql-server

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;

Related

extracting certain size data from column

I have a table in MS SQL Server 2016. the table has a column called notes varchar(255)
The data that contains in the notes column contains notes entry by end user.
Select ServiceDate, notes from my_table
ServiceDate, notes
--------------------------------------
9/1/2022 The order was called in AB13456736
9/1/2022 AB45876453 not setup
9/2/2022 Signature for AB764538334
9/2/2022 Contact for A0943847432
9/3/2022 Hold off on AB73645298
9/5/2022 ** Confirmed AB88988476
9/6/2022 /AB9847654 completed
I would like to be able to extract the word AB% from the notes column. I know the ABxxxxxxx is always 10 characters. Because the ABxxxxxx always entered in different position, it's difficult to use exact extract where to look for. I have tried substring(), left() functions and because the value AB% is always in different positions, I can't get it to extract. is there a method I can use to do this?
thanks in advance.
Assuming there is only ONE AB{string} in notes, otherwise you would need a Table-Valued Function.
Note the nullif(). This is essentially a Fail-Safe if the string does not exist.
Example
Declare #YourTable Table ([ServiceDate] varchar(50),[notes] varchar(50)) Insert Into #YourTable Values
('9/1/2022','The order was called in AB13456736')
,('9/1/2022','AB45876453 not setup')
,('9/2/2022','Signature for AB764538334')
,('9/2/2022','Contact for A0943847432')
,('9/3/2022','Hold off on AB73645298')
,('9/5/2022','** Confirmed AB88988476')
,('9/6/2022','/AB9847654 completed')
Select *
,ABValue = substring(notes,nullif(patindex('%AB[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%',notes),0),10)
from #YourTable
Results
ServiceDate notes ABValue
9/1/2022 The order was called in AB13456736 AB13456736
9/1/2022 AB45876453 not setup AB45876453
9/2/2022 Signature for AB764538334 AB76453833
9/2/2022 Contact for A0943847432 NULL
9/3/2022 Hold off on AB73645298 AB73645298
9/5/2022 ** Confirmed AB88988476 AB88988476
9/6/2022 /AB9847654 completed NULL

How to insert username in VS2008(report edition)

I'm creating a new report (*.rdl), and there I want to add username who runs the script (insert).
I've tried on VS2008 through "built-in-fields" function which is "User ID", but it didn't work:
CREATE TABLE #Some_Table
(
Plan_date date null,
Plan_customer int null,
creator_id nvarchar(55) null
)
INSERT INTO Some_Table
(
[Plan_date] ,
[Plan_customer],
[creator_id]
)
SELECT
#p_plan_monthly,
#p_plan_clients,
#creator_id ="user id" --from built-in-fields
Expected result is: Column creator_id is filling with value of username from active directory who made insert through my report.
To reiterate my comment, as it's is incredibly important:
"You need to use a different account to access your data #whitefang. The sa account should never be used for something as mundane as a report. In truth it should never be used unless you really need sysadmin privileges, or you're doing something like recovering the server. You should have a service account that can do the respective tasks it needs to. If you can suffer injection through those reports, you're service is like an open book to whomever has access."
Now, onto your problem. I would add a further internal parameter on your report. Change the value of the parameter to have the default value of =User!UserID; this will be the ID of the user running the report (perhaps something like StackOverflow\Larnu).
Then map that report parameter to your dataset parameter #creator_id and change your INSERT statement to:
INSERT INTO Some_Table ([Plan_date],
[Plan_customer],
[creator_id])
VALUES (#p_plan_monthly, #p_plan_clients, #creator_id);
Q: "and there I want to add username who runs the script (insert)"
You can use these functions.
-- database user name
SELECT USER_NAME()
-- login identification name
SELECT SUSER_NAME()

Similar google emails check for duplicate

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')

Oracle ROWTOCOL Function oddities

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

How to parse data in SQL Server 2008?

I have a column name called Username in my table in SQL Server 2008.
Username has following data
Username
corp\abc
corp\petern
corp\timw
and so on
I need my Username to be
Username
abc
petern
timw
how do I parse the data in Username to skip corp\ ?
Thanks.
You could use PARSENAME to split the data but the function uses dot (.) as the delimiter. So, you have to first replace the backward slashes (\) with period or dot (.).
Click here to view the demo in SQL Fiddle.
Script:
CREATE TABLE users
(
username VARCHAR(30) NOT NULL
);
INSERT INTO users (username) VALUES
('corp\abc'),
('corp\corporate\'),
('corp\yescorp'),
('corp\def'),
('\corpabc\'),
('corpabc\');
SELECT username
, PARSENAME(REPLACE(username, '\', '.'), 1) AS usernameonly
FROM users;
Output:
USERNAME USERNAMEONLY
----------------- ------------
corp\abc abc
corp\corporate\
corp\yescorp yescorp
corp\def def
\corpabc\
corpabc\
You might use following expression to extract username:
select substring (username, charindex ('\', username, 1) + 1, len(username))
If there is no backslash in username function will return entire username - practical if you mix sql server and Windows authentication.
Update dbo.Users
Set Username = replace(Username, 'corp\\', '');
Please check the quoting beforehand, by first checking whether the results of select seem ok (in general it's a good practice with data updating statements):
select replace(Username, 'corp\\', '') from dbo.Users
You can get the username like this:
SELECT RIGHT('corp\username',LEN('corp\username')-PATINDEX('%\%','corp\username'))
=>
SELECT RIGHT(username,LEN(username)-PATINDEX('%\%',username))
This work on text, nvarchar(n - max)

Resources