How do I update multiple sets procedure - sql

I've having problem with regular expression for updating the multiple set for email that doesn't work at all. You see I'm trying to update from.
alisonsmith#gmail.com
bobgraves#hotmail.com
smithers#yahoo.com
011013092949#msn.ca
011513025559#aol.ca
101513025559#MSN.COM
To the result should look like this:
alisonsmith#dony.com
bobgraves#dony.com
smithers#dony.com
011013092949#dony.com
011513025559#dony.com
101513025559#dony.com
I've tried that update procedure like this and it didn't work at all:
update dony_membership
set Email = LEFT(Email,12)+'#dony.com'
set Email = LEFT(Email,0)+'#dony.com'
where Email LIKE '%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]#%'
or Email LIKE'#%'

As it seems like you want to change the part after the #-sign for all rows I wouldn't bother with regular expressions but rather just keep what ever comes before the #-sign and append the new domain (dony.com) to it:
update dony_membership
set email = left(email, charindex('#', email, 0)) + 'dony.com'
Sample SQL Fiddle for your viewing pleasure :)

Related

SQL Query loop in Postgresql

I have DB in Postgresql 12 and PgAdmin 4 and a lot of queries like:
update public.register set address = replace(address,'Á','A') where address like '%Á%';
update public.register set address = replace(address,'Â','A') where address like '%Â%';
update public.register set address = replace(address,'Ã','A') where address like '%Ã%';
update public.register set address = replace(address,'Ä','A') where address like '%Ä%';
update public.register set address = replace(address,'Å','A') where address like '%Å%';
I want to declare arrays like this:
SET array1 = ARRAY['Á','Â','Ã','Ä','Å]
SET array2 = ARRAY['A','A','A','A','A']
and make a loop just like:
for(i=0; i<count(array1[]); i++){
update public.register set address = replace(address,array1[i],array2[i]) where address like '%array1[i]%';
}
I have not found any good and working idea on forums.
Thanks for any info about this :)
You don't need a loop. This can be done using a single UPDATE statement using regexp_replace()
update register
set address = regexp_replace(address, '[ÁÂÃÄÅ]', 'A', 'g')
where address ~ '[ÁÂÃÄÅ]';
'[ÁÂÃÄÅ]' matches each character in the list. The 'g' option will replace all occurrences in the value.
The WHERE clause then makes sure that only those rows that contain these characters in the address column are changed.
It would work without the WHERE as well, as the regexp_replace() will not change the address if the characters aren't contained. But it's good coding practice to only update those rows that do actually change.
Another option is to install the unaccent extension, then you can use:
update register
set address = unaccent(address)
where address <> unaccent(address);
This has the additional benefit, that you can use language specific rules if you want.

How can I stop executing code after getting a result?

I have a textbox named "Search" and code that filters a customer out by name. I also want to display the whole table if the textbox is empty but don't know how to do it.
NOTE : I am using Microsoft Access.
Here is my code :
SELECT * FROM Customers
WHERE Forms.[Form1].[Text4] = Forms.[Form1].[Text4] AND FirstName=Forms.[Form1].[Text4];
Thank you for any help.
You need validate if text is empty or filter to another rules, this can be something like this:
SELECT * FROM Customers WHERE Forms.[Form1].[Text4] IS NULL OR FirstName = Forms.[Form1].[Text4];

Changing values in fields based on wild card searches between two tables

I want to set the chosen field to true in table e:\ctw for all records of field name which are not like name2 in the d:\le table. The 'ctw.name' records have equal or more characters than the le.name2 records so I want to implement wild card searches; for example,
le.name2 = abc,
ctw.name = abc\12a
So, I want to use a wild card search like 'abc%', but without hard coding a record value. That is, I want to know whether it is possible to combine a field name with wildcard search as below:
UPDATE ctw SET chosen = .t. WHERE LOWER(name) NOT LIKE ((select LOWER(name2) from le)+'%')
I get a function name is missing ) error upon command input.
Try it like this:
SET ANSI OFF
UPDATE ctw ;
SET chosen = .t.
WHERE LOWER(name) NOT IN (select LOWER(name2) from le)
Probably this is what you mean:
UPDATE ctw SET chosen = .t. ;
from le ;
where LOWER(name) LIKE lower(trim(le.Name2))+'%'
And because, by default VFP comparisons in SQL are not ANSI this would mean the same:
UPDATE ctw SET chosen = .t. ;
from le ;
where LOWER(name) = lower(trim(le.Name2))
But I wouldn't trust the non-ANSI implementation and use the ANSI implementation with LIKE.

Send e-mail when a row changes

I will try to best explain what I would like to do (for simplicity I only included two columns that I am working with):
I have two different tables, dbo.device and dbo.devicestatus.
They are both tied by DeviceDN which is primary key.
On dbo.devicestatus, there are two columns called TonerLowB and TonerLowY that can have a value of either 1 or 0.
What I would like to do is have the application (SQLExpress 2008) send an e-mail when one of the rows of TonerLowB or TonerLowY has it's value updated to "1", but not when it has it's value updated to "0" and have that row "merged" with the data from dbo.device.
What I managed to do so far is combine the data from dbo.device with the data from dbo.devicestatus and show just values that are greater than 0 as a select statement:
`
select d.DeviceDN, s.TonerLowB, s.TonerLowY
from dbo.Device d,
dbo.DeviceStatus s
where
d.DeviceDN = s.DeviceDN
and s.TonerLowB + s.TonerLowY > 0 ;
`
I then tinkered with sp_send_dbmail to see if I can send the results via mail and I did manage to do that after defining a profile and creating myself a test mail server. I used the following command:
`
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'MyMailProfile',
#recipients = 'alex#testing.ro',
#query = 'select d.DeviceDN, s.TonerLowB, s.TonerLowY
from dbo.Device d,
dbo.DeviceStatus s
where
d.DeviceDN = s.DeviceDN
and s.TonerLowB + s.TonerLowY > 0 ;' ,
#subject = 'Your Query Results',
#attach_query_result_as_file = 1 ,
#query_result_separator = '|' ;
`
The problem is that this sends me all the lines that have a value greater than 1 and I don't know how to send for each update and just for the updated row instead of this "bulk" method.
I am thinking of adding two new columns to the database db.devicestatus, TonerLowB_LastUpdate and TonerLowY_LastUpdate, both set up as "datetime".
Then I wanted to create two triggers that would update TonerLowB_LastUpdate or TonerLowY_LastUpdate with "set gettime()" when TonerLowB or TonerLowY updates it's value and also send an e-mail with the line that changed it's value (using the mail procedure I mentioned above), if that date is older than 3 days.
Unfortunately I don't know how to declare this trigger and this is what I am trying to find help on.
Would this be possible and if so, would it be a good (reliable) mechanism?
A wise way would be use 'Triggers' in this context.
Take a look at this post to get started on this
Using Triggers to do actions after specific values are updated
To summarize, define an update trigger on the field:
CREATE TRIGGER TonerValueChanged
ON DeviceStatus
AFTER UPDATE
AS
BEGIN
// here you need to check for the condition if the value is updated to 1 and send the mail
END
Now on every value updated, based on your condition, the mail will be triggered
for every row update.
Hope this helps.

I'm in need of a sanity check on a sql query that will return a value if it exists in the table or return a default value if it doesn't

What I'm trying to do is return a mailbox location for a select few users and a catch all mailbox location for everyone else. In postfix you can pass it a query in the of the form
SELECT mailbox FROM virtual_mailboxes WHERE email = '%s'
and it will replace %s with the email user it's looking for. I have a table that contains a set of users that need their own mailbox(root, support, postmaster) and I want to be able to create a query that returns the configured mailbox or 'all/'. For example if the username is 'support' then I want it to pull the mailbox column for username 'support'. If the username is 'anybody' which doesn't match an rows in the table I want it to return 'all/'.
Here is the query I came up with.
SELECT
CASE
WHEN v2.username IS NOT NULL THEN v2.mailbox
ELSE 'all/'
END AS mailbox2
FROM virtual_mailboxes v1
LEFT JOIN virtual_mailboxes v2 ON v2.username = SUBSTRING_INDEX('support#gmail.com', '#', 1)
LIMIT 1
It works but I feel like it's very wrong to do it that way and I'm curious if there is a better way.
One other thing, postfix will only replace the first occurrence of %s. Thanks for any help.
SELECT coalesce(
(SELECT mailbox FROM virtual_mailboxes WHERE email = '%s'),
'all/'
);