nested if-statement to change suffix - ms-access

pls give me the SQL to copy and paste in order to make an nested if statement that meets the following 3 conditons. Thank you very much in advance:
where if the field “Activity Number” doesn’t contain the character "/” e.g ”1-100ZUOM1”, then add a suffix ”/1” e.g. ”1-100ZUOM1/1”
if it already does contain a suffix like ”/1” e.g. ”1-100ZUOM1/1”, then change the last character to “2” e.g. ”1-100ZUOM1/2”
if it already does contain a suffix like ”/2” e.g. ”1-100ZUOM1/2”, then change the last character to “3” e.g. ”1-100ZUOM1/3”
INSERT INTO tbl_All_workorders ( [Activity Number] )
SELECT AW.[Activity Number]
FROM tbl_All_workorders AS AW;

Consider altering your design so that Activity Number is stored split into two columns so that the suffix appears in its own integer column. This way, your SQL updates will be far easier to maintain and the Activity Number can be easily concatenated for display, possibly using a VIEW.

Related

Anyway to filter access records containing an '#'?

I have an Access database that is being used for a website. In the DB there is a field for image file names that is used to display images on the site. In some case the person responsible for gathering the images started using the # character in the image file names when saving them and this is causing the images not show on the website.
Is there anyway to filter out just the records where the image field contains the '#' character?
Everything I've tried has Access treating it like a wildcard and picking up any number.
As mentioned in a comment, you can select rows which have # contained in your image_file_name field by checking whether the field is LIKE '*[#]*'
However, since you want to filter out those rows, target the inverse of that pattern match ... NOT LIKE '*[#]*'
A query like this would work within an Access session with default settings:
SELECT y.*
FROM YourTable AS y
WHERE y.image_file_name Not Like '*[#]*';
However, since you're using the Access db to feed a website, you may be using ADO/OleDb to connect to the db file. If that is the case, use % instead of * as the wildcard character:
WHERE y.image_file_name Not Like '%[#]%';
Or you could use Alike instead of Like. In that situation, the wildcard should always be % and the query will work correctly whether you're running it from within or outside of Access:
WHERE y.image_file_name Not ALike '%[#]%';
A totally different approach is to use InStr to find the position of # within image_file_name and select the rows where InStr returns zero:
SELECT y.*
FROM YourTable AS y
WHERE InStr(1, y.image_file_name, '#') = 0;
If you also want rows where image_file_name is Null, you can add that condition to the WHERE clause with OR.

Need to create a custom query

I need to clear out invalid users created by a scipted attack from the database.
The query would:
check if row name "about:me" contains "michael kors"
if yes, then set row "account_status" to "inactive"
I'm a very novice "DBA" so I'm hoping an example of a correct query in this case will help me to be able to construct others and help other users do the same.
If the column name is really about:me (a colon would be unusual), and account_status is actually a text field (not an integer indicating active/inactive), and imagining your table is named users (you didn't say), something like this would work:
update users
set account_status = 'inactive'
where `about:me` like '%michael kors%';
The backticks allow unusual characters like : to appear in the column name; the % allows varying whitespace (or other random characters) around the name when used with like; the like also allows us to match regardless of upper/lowercase in the name column.
assuming you're describing a table 'tbl' with fields 'about:me' and 'account_status', you should be able to run an UPDATE with a WHERE to do this. Something like...
UPDATE tbl
SET account_status = 'inactive'
WHERE `about:me` LIKE '%michael kors%';
Note this uses LIKE which means it's case insensitive and uses the wildcard character % to match anything containing michael kors.
Hope it helps!

Performance of LIKE 'xyz%' v/s LIKE '%xyz'

I was wondering how the LIKE operator actually work.
Does it simply start from first character of the string and try matching pattern, one character moving to the right? Or does it look at the placement of the %, i.e. if it finds the % to be the first character of the pattern, does it start from the right most character and starts matching, moving one character to the left on each successful match?
Not that I have any use case in my mind right now, just curious.
edit: made question narrow
If there is an index on the column, putting constant characters in the front will lead your dbms to use a more efficient searching/seeking algorithm. But even at the simplest form, the dbms has to test characters. If it is able to find it doesn't match early on, it can discard it and move onto the next test.
The LIKE search condition uses wildcards to search for patterns within a string. For example:
WHERE name LIKE 'Mickey%'
will locate all values that begin with 'Mickey' optionally followed by any number of characters. The % is not case sensitive and not accent sensitive and you can use multiple %, for example
WHERE name LIKE '%mouse%'
will return all values with 'mouse' (or 'Mouse' or 'mousé') in it.
The % is inclusive, meaning that
WHERE name like '%A%'
will return all that starts with an 'A', contain 'A' or end with 'A'.
You can use _ (underscore) for any character on a single position:
WHERE name LIKE '_at%'
will give you all values with 'a' as the second letter and 't' as the third. The first letter can be anything. For example: 'Batman'
In T-SQL, if you use [] you can find values in a range.
WHERE name LIKE '[c-f]%'
it will find any value beginning with letter between c and f, inclusive. Meaning it will return any value that start with c, d, e or f. This [] is T-SQL only. Use [^ ] to find values not in a range.
Finding all values that contain a number:
WHERE name LIKE '%[0-9]%'
returns everything that has a number in it. Example: 'Godfather2'
If you are looking for all values with the 3rd position to be a '-' (dash) use two underscores:
WHERE NAME '__-%'
It will return for example: 'Lo-Res'
Finding the values with names ends in 'xyz' use:
WHERE name LIKE '%xyz'
returns anything that ends with 'xyz'
Finding a % sign in a name use brackets:
WHERE name LIKE '%[%]%'
will return for example: 'Top%Movies'
Searching for [ use brackets around it:
WHERE name LIKE '%[[]%'
gives results as: 'New York [NY]'
The database collation's sort order determines both case sensitivety and the sort order for the range of characters. You can optionally use COLLATE to specify collation sort order used by the LIKE operator.
Usually the main performance bottleneck is IO. The efficiency of the LIKE operator can be only important if your whole table fits in the memory otherwise IO will take most of the time.
AFAIK oracle can use indexes for prefix matching. (like 'abc%'), but these index cannot be used for more complex expressions.
Anyway if you have only this kind of queries you should consider using a simple index on the related column. (Probably this is true for other RDBMS's as well.)
Otherwise LIKE operator is generally slow, but most of the RDBMS have some kind of full text searching solution. I think the main reason of the slowness is that LIKE is too general. Usually full text indexes has lots of different options which can tell the database what you really want to search for, and with these additional information the DB can do its task in a more efficient way.
As a rule of thumb I think if you want to search in a text field and you think performance can be an issue, you should consider your RDBMS's full text searching solution, or the real goal is not text searching, but this is some kind of "design side effect", for example xml/json/statuses stored in a field as text, then probably you should consider choosing a more efficient data storing option. (if there is any...)

Creating variables and reusing within a mysql update query? possible?

I am struggling with this query and want to know if I am wasting my time and need to write a php script or is something like the following actually possible?
UPDATE my_table
SET #userid = user_id
AND SET filename('http://pathto/newfilename_'#userid'.jpg')
FROM my_table
WHERE filename
LIKE '%_%' AND filename
LIKE '%jpg'AND filename
NOT LIKE 'http%';
Basically I have 700 odd files that need renaming in the database as they do not match the filenames as I am changing system, they are called in the database.
The format is 2_gfhgfhf.jpg which translates to userid_randomjumble.jpg
But not all files in the database are in this format only about 700 out of thousands. So I want to identify names that contain _ but don't contain http (thats the correct format that I don't want to touch).
I can do that fine but now comes the tricky bit!!
I want to replace that file name userid_randomjumble.jpg with http://pathto/filename_userid.jpg So I want to set the column user_id in that row to a variable and insert it into my new filename.
The above doesn't work for obvious reasons but I am not sure if there is a way round what I'm trying to do. I have no idea if it's possible? Am I wasting my time with this and should I turn to PHP with mysql and stop being lazy? Or is there a way to get this to work?
Yes it is possible without the php. Here is a simple example
SET #a:=0;
SELECT * FROM table WHERE field_name = #a;
Yes you can do it using straightforward SQL:
UPDATE my_table
SET filename = CONCAT('http://pathto/newfilename_', userid, '.jpg')
WHERE filename LIKE '%\_%jpg'
AND filename NOT LIKE 'http%';
Notes:
No need for variables. Any columns of rows being updated may be referenced
In mysql, use CONCAT() to add text values together
With LIKE, an underscore (_) has a special meaning - it means "any single character". If you want to match a literal underscore, you must escape it with a backslash (\)
Your two LIKE predicates may be safely merged into one for a simpler query

MySQL: REGEXP to remove part of a record

I have a table "locales" with a column named "name". The records in name always begin with a number of characters folowed by an underscore (ie "foo_", "bar_"...). The record can have more then one underscore and the pattern before the underscore may be repeated (ie "foo_bar_", "foo_foo_").
How, with a simple query, can I get rid of everything before the first underscore including the first underscore itself?
I know how to do this in PHP, but I cannot understand how to do it in MySQL.
SELECT LOCATE('_', 'foo_bar_') ... will give you the location of the first underscore and SUBSTR('foo_bar_', LOCATE('_', 'foo_bar_')) will give you the substring starting from the first underscore. If you want to get rid of that one, too, increment the locate-value by one.
If you now want to replace the values in the tables itself, you can do this with an update-statement like UPDATE table SET column = SUBSTR(column, LOCATE('_', column)).
select substring('foo_bar_text' from locate('_','foo_bar_text'))
MySQL REGEXs can only match data, they can't do replacements. You'd need to do the replacing client-side in your PHP script, or use standard string operations in MySQL to do the changes.
UPDATE sometable SET somefield=RIGHT(LENGTH(somefield) - LOCATE('_', somefield));
Probably got some off-by-one errors in there, but that's the basic way of going about it.