I am attempting to create my first SQL Audit and I've ran into a bit of a snag. I have two tables, a temp table that has the Audit log, and a table with Lastnames (lets call it tblLastName).
Now, the audit is against anything with a SELECT against specific tables and I want to take the results and compare them with my Last Name table. Basically, in the Audit table is the statement column, in there will be something similar to
where lastname like %personslastname%
How might I go about getting just the value between the % % to compare it against the lastnames table.
At the moment I can get which rows have a last name selected against, but I do not know how to turn that into anything useful. My logic I thought would work would be to get the rows that have a last name, get the substring (which is where i am stuck) of that row to get just the name, store that name in a variable, and then compare against the other table. Unfortunately all I have so far is:
select * from #MyTempTable where statement like '%LastName like%'
Any help would be appreciated. Also it is SQL Server 2008.
Edit for data:
SELECT vLastName from tblLastName
produces results like:
Super User,
Hendrix,
Greenwood,
Page,
My Audit Statement is much more in depth though so I've taken a bit out:
select DISTINCT
x.ReceiveMail as [Receive Mail],
x.ParticipantID as [Participant ID],
x.LastName as [Last Name],
x.FirstName as [First Name],
x.AliasName as [Alias Name], ......
where x.LastName like '%Greenwood%'
AND (x.FirstName like '%Jonny%' OR x.AliasName like '%Jonny%')
Related
I have a query where fields are as follows:
UniqueID | RefNum | FirstName | Surname | Aim |.....
UniqueID - is a unique field (no duplicates)
RefNum - contains duplicates
What I'm trying to do is to create a new query (based on the above or amend this one) to extract only records with unique RefNum (remove duplicates from the RefNum field)
The way I did it was select 'Group By' RefNum in the Query Design View and selecting 'First' for the rest of the fields. It achieves what I need.
The problem is that if I switch to the Datasheet View (and subsequently export it to excel to be sent out) the field names are 'FirstOfUniqueID', 'FirstofFirstName', 'FirstOfSurname', etc. Is there a way of keep the original field names (not prefixing them with 'FirstOf') or is there another way of achieving it?
The query designer automatically assigns an alias for a field expression which is based on an aggregate function. So, if you switch from Design View to SQL View for your query, you will see something like this included in the SELECT field list ...
First(FirstName) AS FirstOfFirstName
You can change the alias to something else, and you have a lot of flexibility. However, at least in some cases, when you attempt to re-use the base field name as the alias, Access complains about a "circular reference". I don't know whether that would happen here, but you can try it like this ...
First(FirstName) AS [FirstName]
Whether or not that does what you want, I'll suggest you consider a different query strategy which almost completely avoids the field name alias issue. First test this query to confirm it returns suitable RefNum/UniqueID pairs. If your base query is named Query1 ...
SELECT q1.RefNum, Min(q1.UniqueID) AS MinOfUniqueID
FROM Query1 AS q1
GROUP BY q1.RefNum
Assuming that one returns the correct rows, join it back to the base query to select only the base query rows which match ...
SELECT q.*
FROM
Query1 AS q
INNER JOIN
(
SELECT q1.RefNum, Min(q1.UniqueID) AS MinOfUniqueID
FROM Query1 AS q1
GROUP BY q1.RefNum
) AS sub
ON q.UniqueID = sub.MinOfUniqueID
If you switch the view of your query to SQL view, you will see for example AS FirstOfFirstName.
Change this to AS FirstName and follow this on the other fields.
If you prefer doing this in design view you can do so by adding FirstName:
in front of the fieldname and so on:
I'm working through an SQL injection tutorial. I don't understand one aspect of an SQL statement which is used determine where the different columns in the table will be displayed on the web page and then used to execute statements. A previous SQL injection statement has been used to determine the number of columns in the table, which is 6. The SQL statement is
SELECT * FROM TableName Where id=12 union all select 1,2,3,4,5,6
I've researched the SELECT and UNION ALL statements and haven't been able to work out what is actually going on. My thinking is that the numbers in the 2nd select statement respresent the column numbers.
The second statement used to get the values from the table is:
SELECT * FROM TableName Where id=12 union all select 1,2,3,4,user(),6
What does the select 1,2,3,4,5,6 and select 1,2,3,4, user(),6 component of the SQL injection query actually do?
They are not column numbers but values. Assuming you can somehow inject the statement you now need something to do with it. The first example counts the columns. theUNION will fail when there are not enough columns. By adding more columns to the UNION eventually the statement will execute. Now you know how many columns there are.
The second one is injecting the user into the return result set. Assuming the result set gets displayed on the screen for some reason, you now have a user name (or service account name) with which to execute more statements on your database, escalate privileges or make service calls.
It's doing something like that. Without knowing more it's hard to know what exactly.
I am working with Excel spreadsheets that I'm importing into MS Access. They include a client name, date of birth, some other personal information, and order information. The same clients often have multiple, unique orders. I am creating a table that is just unique clients (which I'll link to the order table later) and so when I import data from Excel I would like to delete duplicate client records, preserving one. I would like to match them on Name and Date of Birth. The issue I'm running into is that some client names are strings that don't match exactly.
For example:
Name DOB
---- ---
DOE,JOHN 1/1/1960
DOE,JOHN L 1/1/1960
JOHNSON,PAT 12/1/1945
SMITH,BETTY 2/1/1935
In the above set I'd like to limit it to just three records and remove an excess John Doe record.
I basically would like to only look at the client name before the space.
I wouldn't be opposed to losing the middle initial totally, so if there's a way to just chop it off, that'd work too. How can I achieve this?
Sounds like your easiest option is to in fact cut off any middle initals.
You'll want to process as follows.
Use Select DISTINCT when all done and said.
If you use the InStr function Syntax HERE , you can search for the space after the first name.
you can then choose to select only what's left of that with the Left function (left minus 1 as to not include the space). You'll come up with an error if a space isn't found, so add and iif statement to simply output just the name.
After reviewing the data, you'll need to remove column 1 (in the example below) as well as insert the Expr1 code directly into the iif statement, so in the end you'll only have two columns: DOB and Expr2 (or rename AS Name)
Here's an example:
SELECT DISTINCT
Table1.Name,
Table1.DOB,
InStr(1,[Table1].[Name]," ",1) AS Expr1,
IIf([expr1]>0,Left([Table1].[Name],[Expr1]-1),[Table1].[Name]) AS Expr2
FROM Table1;
Wayne beat me to it..
Thank all of you for your help. My Access database is coming along nicely.
My new question is:
I have three fields that are to be considered to get the result I am looking for.
Date, EMPID and the RESULTS field.
The date is simply a date with no time.
The EMPID is a unique employee identifier.
The Results field states either pass or fail.
What I am trying to do is on any single date (there may be many dates, but each is to be considered separately) an employee may test many times and have multiple failures (there can only ever be one passing result). If on the same date the same employee passes, then all fails are to be removed. If there is no pass, then leave one fail.
Thank You,
Query 1: QueryPass
SELECT *
FROM Table1
WHERE Results="Pass";
Query 2: QueryFail
SELECT *
FROM Table1
WHERE EmpID & ResDate Not In (SELECT EmpID & ResDate FROM QueryPass);
Query 3: QueryReport
SELECT EmpID, ResDate, Results FROM QueryFail
UNION SELECT EmpID, ResDate, Results FROM QueryPass;
NOTE: Date is a reserved word in Access, should avoid using reserved words as names for anything.
Since there can be multiple rows per person (and all in the same table), and if someone passes, it will be the 'last' record for that person, the following will give you what you need.
SELECT Last(Table1.[TestDate]) AS LastOfTestDate,
Table1.[EMPID], Last(Table1.[TestResult]) AS LastOfTestResult
FROM Table1
GROUP BY Table1.[EMPID];
I'm making a form in Access to search a database. I want to be able to use a combo box to let the user know the values that exist in the database. Specifically, something like this.
This works perfectly, however, I'd also like to be able to use the "*" wildcard as an option. In a Value List, it would be as simple as "*";"value1";"value2";etc. but this doesn't seem to work when using a query.
EDIT: I found this. It seems like a different way of solving the problem. I'm still open for suggestions.
Say your combo uses this SELECT statement as it's row source.
SELECT DISTINCT dept_name
FROM Departments
ORDER BY dept_name;
If you want a row with "*" in addition to rows for the unique department names, you can use a UNION query.
SELECT dept_name
FROM Departments
UNION
SELECT "*" AS dept_name
FROM SmallTable
ORDER BY 1;
You don't need the DISTINCT keyword because UNION returns only the unique values from the combined record sets.
You don't actually need to alias the field expression ("*" AS dept_name) in the second SELECT ... the database engine will be happy as long as the data type is compatible with dept_name.
I chose SmallTable in the second SELECT because you only need a table (or a query or subquery) source with a single row. More than one row will not be a deal-killer however, because UNION will discard duplicates.
Anyway that's my best guess as to what you're looking for. If I guessed wrong, clarify what you want and someone will surely give you a better answer.