I have table in SQL Server as below :
+--------------+----------------------------------------------+
| reportName | ShareWith |
+--------------+----------------------------------------------+
| IBM SH data | [email protected],[email protected],[email protected] |
| Samsung Sr | [email protected],[email protected] |
| Xiaomi MFG | |
| Apple US st | [email protected],[email protected] |
| LG EU | [email protected] |
+--------------+----------------------------------------------+
In my php file, I have an input text and a button. When a user type a report name and click on the button tt will perform an ajax call to remove the current user email from the selected report.
In SQL it should be as below :
select shareWith, UpdatedshareWith =
case
when shareWith like '[email protected],%' then REPLACE(shareWith, '[email protected],', '')
when shareWith like '%,[email protected],%' then REPLACE(shareWith, ',[email protected],', ',')
when shareWith like '%,[email protected]' then REPLACE(shareWith, ',[email protected]', '')
when shareWith = '[email protected]' then ''
else shareWith
end
from table
where reportName = 'xxxx';
I’m trying to apply it dynamically in PHP but couldn’t make it work.
$('#button').on('click', function(){
var reportName = x;
var username = y;
$.ajax({
type: "POST",
url: "delete.php",
data: { reportName : reportName,
username : username },
success: function(data) { console.log(data); }
});
});
and delete.php as below :
$stmt = $conn->prepare("UPDATE table SET shareWith = CASE
WHEN shareWith like '?,%' THEN REPLACE(shareWith, '?,', '')
WHEN shareWith like '%,?,%' THEN REPLACE(shareWith, ',?,', ',')
WHEN shareWith like '%,?' THEN REPLACE(shareWith, ',?', '')
ELSE shareWith
END
WHERE reportName = ?");
$stmt->execute([$_POST['username'], $_POST['username'], $_POST['username'],
$_POST['username'], $_POST['username'], $_POST['username'], $_POST['reportName']]);
echo json_encode('deleted');
I believe there is a cleaner way to do it. Any suggestions please what should i change in my code ? Thank you very much.
2
Answers
You desperately need to fix the schema. Storing multiple values in a string is just wrong. But sometimes we are stuck with other people’s really, really, really bad decisions.
I would suggest this structure:
That is, simplify the logic by putting delimiters around the searched string and the pattern.
However, I will repeat: you should have a table with one value per report and share.
Instead of the more flexible
TRIM()
, you can use spaces andTRIM()
andREPLACE()
instead:This assumes that the string doesn’t have spaces, which makes sense for emails in a string.
Please try the following solution.
It will work starting from SQL Server 2012 onwards.
It is using XML and XQuery to tokenize email list, and remove not needed email. You can package it as a stored procedure with two parameters, @reportName and @emailToRemove.
The CTE does all the heavy lifting:
SQL
Output