I need to do a like search, in my SQL Server database. BUT, how do I do this, while still using parameters for my search value?
I am not talking about encapsulating in %'s. I need to be able to add a % in the middle of the search word.
WHERE title LIKE '%foo%bar%'
as an example, but with params.
Edit:
To elaborate on the params:
I am using MS SQL 2008, and C#, so it would be:
WHERE title LIKE '#SearchParam'
and #SearchParam would then be set to "%foo%bar%".
I hope that makes sense?
This works fine
create proc dbo.lookupWild(#LIKEclause VARCHAR(20))
as
begin
select * from teams where Name like #LIKEclause
end
go
exec lookupWild 'E%G%'
And things like '1=1 -- drop table' are not SQL injected, they are just part of the wildcard search
This should work fine if you are using Stored Procedures. Here is a similar thread.
How to Escape Wildcard Characters While Searching in SQL Server
Are you looking for something like below?
where title like '%foo[%]bar%'
Related
Lets say I have a query like this:
Parameters Table_Name string, Field_Name string;
Update Table_Name Set Table_Name.[field1] = "new value", Table_Name.[field2] = "new Value" Where Table_Name.[Field_Name] = "Some value"
Basically I have the same query which I need to run against different tables which share some fields together. I want to be able to type the table name when I run the query.
I know this can be achieved with VBA, but this way would be a lot easier than VBA. Although VBA is also welcome but I would like to be able to do this in pure SQL.
How to achieve the above logic for table names AND field names?
Is this being done in MSAccess or in SQL Server? If you've got a SQL Server behind things, then you'll be looking to do some sp_executesql calls to get the job done. If you're doing this in MSAccess, you can accomplish the same by building dynamic SQL statements in VBA - either way would work if you've got Access pointing to SQL, though.
I want to search for specific text in all procedures/functions etc. in all databases. I managed to create the required query from this answer but it looks like OBJECT_DEFINITION(OBJECT_ID(SPECIFIC_NAME)) returns NULL for all DBs except the current one.
sp_msforeachdb 'SELECT ''?'' AS DB, SPECIFIC_NAME, OBJECT_DEFINITION(OBJECT_ID(SPECIFIC_NAME)) FROM [?].INFORMATION_SCHEMA.ROUTINES'
You absolutely need Red-Gate's SQL Search tool - it's FREE, and absolutely great and perfectly suited for this need.
The problem is OBJECT_ID cannot be used that way. It only works on the current database. Try returning ROUTINE_DEFINITION directly from INFORMATION_SCHEMA.ROUTINES. This does have a limit of 4000 characters. I'll try to find my other answer on SO which gives my workaround using the MS metadata views.
Have a look at this:
Can you search SQL Server 2005 Stored Procedure content?
try this:
select * from syscomments where [text] like '%yourKeyword%'
is there a simple way to just output each record in a select statement to write to its own file?
for example, if you have the tsql query in sql server 2005,
select top 10 items, names + ':' + address from book
and you ended up with 10 text files with the individual name and addresses in each file.
is there a way to do this without writing an extensive spWriteStringToFile procedure? I'm hoping there is some kind of output setting or something in the select statement.
thanks in advance
SQL returns the result set first, there's no opportunity in there for writing records to specific files until afterwards.
Being SQL Server 2005, it's possible you could use a SQLCLR (.NET 2.0 code) function in a SQL statement without having to make a separate application.
In SSMS, you can do a results to file, but that wouldnt split each record out into its own file. I pretty sure you cannot do this out of the box, so it sounds like you will be rolling your own solution.
You'd do this in some client, be it Java, VBA or SSIS typically.
I am trying to execute a pretty-sophisticated query on a string field in the database. I am not very experienced at JPQL, so I thought I would try to get some help.
I have a field in the database called FILE_PATH. Within the FILE_PATH field, there will be values such as:
'C:\temp\files\filename.txt'
'file:\\\C:\testing\testfolder\innerfolder\filename2.txt'
I need to be able to do a search from a user-given query on the file name only. So, instead of simply doing a SELECT Table FROM Table AS t WHERE t.filePath LIKE '%:query%', things will have to get a bit more complicated to accomodate for just the filename portion of the path. The file path and file name are dynamic data, so I can't just hard-code a prefix string in there. This has me pretty confused, but I know there are some string expressions in JPQL that might be able to handle this requirement.
Basically, I just need to return all rows that match the given query on whatever comes after the last '\' in the FILE_PATH field. Is this possible?
Thanks for the help.
EDIT: Database that is being used is SQL Server.
Probably the best solution is to add a separate column that contains just the file name. If you can't, then this might work (depending on the database you use):
drop table test;
create table test(name varchar(255));
insert into test values('C:\temp\name2\filename.txt');
insert into test values('file:\\\C:\\innerfolder\filename2.txt');
select * from test
where substring(name, locate('\', name, -1)) like '%name2%'
This is pure SQL, but as far as I understand all the functions are supported within JPQL: http://www.datanucleus.org/products/accessplatform/jpa/jpql_functions.html
One problem is the locate(,,-1). It means 'start from the end of the string'. It works for the H2 database, but not MySQL and Apache Derby. It might work for Oracle, SQL Server (I didn't test it). For some databases may need to replace '\' with '\\' (MySQL, PostgreSQL; not sure if Hibernate does that for you).
Final WHERE Clause:
LOWER(SUBSTRING(fs.filePath, LENGTH(fs.filePath) - (LOCATE('\\', REVERSE(fs.filePath)) - 2), (LOCATE('\\', REVERSE(fs.filePath)) - 1))) LIKE '%:query%'
NOTE: For performance, you might want to save the location of the slash.
Thanks to Thomas Mueller for the assistance.
As the topic suggests I wish to be able to pass table names as parameters using .NET (doesn't matter which language really) and SQL Server.
I know how to do this for values, e.g. command.Parameters.AddWithValue("whatever", whatever) using #whatever in the query to denote the parameter. The thing is I am in a situation where I wish to be able to do this with other parts of the query such as column and table names.
This is not an ideal situation but it's one I have to use, it's not really prone to SQL injection as only someone using the code can set these table names and not the end-user. It is messy however.
So, is what I am asking possible?
EDIT: To make the point about SQL injection clear, the table names are only passed in by source code, depending on the situation. It is the developer who specifies this. The developer will have access to the database layer anyway, so the reason I am asking is not so much for security but just to make the code cleaner.
You cannot directly parameterize the table name. You can do it indirectly via sp_ExecuteSQL, but you might just as well build the (parameterized) TSQL in C# (concatenating the table-name but not the other values) and send it down as a command. You get the same security model (i.e. you need explicit SELECT etc, and assuming it isn't signed etc).
Also - be sure to white-list the table name.
I don't think I've ever seen this capability in any SQL dialect I've seen, but it's not an area of expertise.
I would suggest restricting the characters to A-Z, a-z, 0-9, '.', '_' and ' ' - and then use whatever the appropriate bracketing is for the database (e.g. [] for SQL Server, I believe) to wrap round the whole thing. Then just place it directly in the SQL.
It's not entirely clear what you meant about it not being a SQL injection risk - do you mean the names will be in source code and only in source code? If so, I agree that makes things better. You may not even need to do the bracketing automatically, if you trust your developers not to be cretins (deliberately or not).
You can pass the table name as a parameter like any other parameter. the key is you have to build a dynamic sql statement, which then you should consider if it's easier to build it in your app tier or in the procs.
create procedure myProc
#tableName nvarchar(50)
as
sp_executesql N'select * from ' + #tablename
fyi this code sample is from memory have a look at BOL for the proper syntax of sp_executesql.
Also this is highly sucesptible to SQL injection as you indicated is not an issue for you but anyone reading this should be very wary of accepting input from a user to generate their queries like this.
SQL query parameters can only take the place of a literal value. You cannot use a parameter for a table name, column name, list of values, or other SQL syntax. That's standard SQL behavior across all brands of database.
The only way to make the table name dynamic is to interpolate a variable into your SQL query before you prepare that string as a statement.
BTW, you're fooling yourself if you think this isn't a risk for SQL injection. If you interpolate the table name into the query dynamically, you need to use delimited identifiers around the table name, just as you would use quotes around a string literal that is interpolated from a variable.
The idea that it is not prone to SQL injection is misguided. It may be less prone to SQL injection from front end users, but it is still very much prone to SQL injection. Most attacks on databases come from inside the company being attacked, not from end users.
Employees may have grudges, they may be dishonest, they may be disgruntled, or they may just be not so bright and think that it's ok to bypass security to do whatever it is that THEY think should be done to the database.
Please see this post answer by user Vimvq1987:
MySqlParameter as TableName
Essentially you first check the table name against the schema, in which the table name is used in a parameterized fashion. Then if all is ok, the table name is legit.
Paraphrased basic idea is:
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'databasename'
AND table_name = #table;
cmd.Parameters.AddWithValue("#table",TableName);
If this returns ok with the table name, go ahead with your main query...
I would just check
select OBJECT_ID(#tablename)
the idea is to prevent injection you know it has to be table name this was if this returns a number then i would run the actual query,