August 22, 2003 at 10:40 am
Arthur, The submission process would need to have the ability to assure a properly formed argument. Is the interface a web page using an ADO object? Is it an internal application? Does the submitting process create a string or create parameters to a stored proc ADO object?
My understanding is that if you are using an ADO Command object (sorry - I;m in c# using SqlCommand, but I think it is similar), you can say <parameter>.value = <some string>. I believe that this may handle the quotes for you, but haven't tested it recently.
If the process puts it into the commandText - the process will need to replace each single quote with two quotes.
Guarddata-
August 22, 2003 at 10:58 am
First of all, many thanks for you guys response. I appreciate it. The basic requirements for my sp is simple, it must be able to store (temporary) in a table for a user's custom sql statement(s). User can execute it/them later - if more than one query, we assume that user wants to UNION the statements. I am allowed to read the VB source code because it is not my department. Therefore, I have no idea what exactly the VB handling. However, I have seen part of the VB code before in elsewhere; I remember that the VB developer is using ADO objects for the project. I discussed my problem with our Oracle Artchitect a while ago, he told me that I am in the right track. Even though I don't like the way I solved this problem but it works fine so far. Again, I am willing to learn a better solution for this issue. Does it make sense now?
Thanks,
AC
August 22, 2003 at 11:03 am
Yep - makes sense. I really don't think there is any problem storing the query as long as they can properly call the stored procedure. The burden is really on the submission.
Guarddata-
August 24, 2003 at 2:49 am
Hopefully I am on the right track. Had a similar problem last week. Solution was to replace all the single quotes in the data with two single qoutes. Problem was product names with single quotes as part of the product name. Includes an example.
Create Table Tmp(Company_Id int IDENTITY(1,1),Company_Name Varchar(100))
GO
Insert Tmp
Select 'Company 1'
Insert Tmp
Select 'Company ''1' -- Application supplied Company '1 but sp replace any single quotes with two single quotes
Insert Tmp
Select 'Company ''1''' -- Aplication supplied Company '1' but sp replace any single quotes with two single quotes
GO
Select * from Tmp
GO
Drop Table Tmp
GO
Result from Select * which is what the user eventually will receive/see
1Company 1
2Company '1
3Company '1'
August 24, 2003 at 3:47 am
-- Part II User commands
-- User supply VB / ASP with "Select * from Tmp Where Company_Name='Company ''1'''"
Set QUOTED_IDENTIFIER off -- More readable
Insert Tmp
Select "Select * from Tmp Where Company_Name='Company ''1'''"
Set QUOTED_IDENTIFIER on
GO
Declare @c Varchar(1000)
Select @c=Company_Name From Tmp Where Company_Id=4
Select 'USER SUPPLIED SQL STATEMENT',@c
Exec (@c)
Go
Drop Table Tmp
GO
August 25, 2003 at 1:40 am
Hi
You can use sp_excutesql sp to create a dynamic sql
e.g sp_executesql(@sqlstmt)
note : @sqlstmt should be nvarchar(4000) maximum.
Another way is execute method.
e.g. exec (@sqlstr)
where @sqlstr contains the any executable select statement.
August 25, 2003 at 9:14 am
Well this is maybe a very stupid reply but maybe it isn't......
1. Pass the sql-query to a stored procedure as a parameter, the quotes issue should be solved then.
2. Dont try to execute the sql-query in SQL itself instead let the VB-Client execute the string........
i.m.h.o this should always work. no problem with quotes etc........
August 25, 2003 at 9:27 am
Of course, it is not a stupid suggestion but I have the basic requirements for my sp. The app pass in a sql statement and my sp has to handle the rest. Therefore, your solution does not applicable for my case. Well, so far I can passed the test from the VB developer. He will inform me if anything is broken. Again, many thanks for you guys helpful information and suggestion. I truely appreciate it.
Many thanks,
AC
August 25, 2003 at 10:13 am
Can you post a sample of what the App sends to the database? That might clear things up for us...
August 25, 2003 at 10:29 am
Well, I did mention the simple sql statement that passed in from the app interface before. Anyhow, here is the statement look like --> 'SELECT * FROM abc WHERE name LIKE 'A%''. Note, the single quotes are added in the beginning and at the end of the string when the VB inteface pass in the string value to my sp. Again, it is just a simple statement and there is no control for what the user created, the sp has to accept any query even it is not runnable and it will only trigger an error when it actually execute. I worked around with this problem by requesting the VB Developer replaced all the single quote into a rarely used character before passing into my sp and I replace it back to a single quote before the statement(s) execute. So far, it works fine. That's it! Any suggestion?
AC
August 25, 2003 at 10:54 am
Here is a quick sample of something that might work for you - it can be adjusted however you need. Hope it helps.
Guarddata-
--DROP table sqlReady
create table sqlReady (
cmdID INT IDENTITY(1,1), --Provide an easy ID
ProcOn DATETIME NULL, --Date on which to execute the command
sqlCmd VARCHAR(4000) NOT NULL, --Command to execute
execed DATETIME NULL --Date command was executed
)
GO
--DROP PROCEDURE PrepareSQLStatement
CREATE PROCEDURE PrepareSQLStatement (
@sqlCmd VARCHAR(4000), --Command to execute
@ProcOn DATETIME = NULL --Date on which to execute the command
) AS
INSERT INTO sqlReady ( ProcOn, sqlCmd )
VALUES ( @ProcOn, @sqlCmd )
RETURN 0
GO
EXEC PrepareSQLStatement @sqlCmd = 'SELECT * FROM authors (NOLOCK) WHERE au_fname LIKE ''j%'''
GO
--select * from sqlReady
--GO
-- SELECT cmdID, sqlCmd FROM sqlReady
-- WHERE ISNULL( ProcOn, GETDATE() - 1 ) < GETDATE()
--DROP PROCEDURE RunPreparedProcs
CREATE PROCEDURE RunPreparedProcs (
@UpToDate DATETIME = NULL
) AS
DECLARE
@toExec NVARCHAR(4000), --To read the command
@procID INT --ID of executed command
SELECT @UpToDate = ISNULL( @UpToDate, GETDATE() )
DECLARE exeCurs CURSOR FOR
SELECT cmdID, sqlCmd FROM sqlReady
WHERE ISNULL( ProcOn, GETDATE() - 1 ) < @UpToDate
OPEN exeCurs
FETCH NEXT FROM exeCurs INTO @procID, @toExec
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC sp_executesql @toExec
UPDATE sqlReady SET execed = GETDATE()
WHERE cmdID = @procID
FETCH NEXT FROM exeCurs INTO @procID, @toExec
END
CLOSE exeCurs
DEALLOCATE exeCurs
RETURN 0
GO
EXEC RunPreparedProcs
Oops - forgot to mention that this is meant to run in the pubs database.
Edited by - guarddata on 08/25/2003 10:55:37 AM
August 25, 2003 at 1:46 pm
My point wasn't as much which query the app passes in, but the method it uses to pass it in. Does it call a stored procedure using the ADOCommand object adding parameters? Or does it parse a complete string and executes that using the ADOConnection.Execute method?
In the first case, there is no need for VB nor for you to worry about the quotes. You can insert the SQLStatement as it is passed into the procedure. To execute use
CREATE ExecuteUserProcedure
<add the selectioncriteria like user, ...>
AS
DECLARE @strSQL as varchar(4000)
SELECT @strSQL = SQLStatement FROM SQLTable WHERE <your selection criteria>
EXEC @strSQL
--or use sp_executesql @strSQL
In my opinion, this is by far the most preferable solution, since you don't have to worry about the quotes and stuff. Removes the possibilitiy of SQLInjection when inserting.
(Still leaves sql injection open when executing the query that a user adds, obviously.)
August 25, 2003 at 1:55 pm
That is actually my original design of my sp and it is still the design but added replace function before execute the sql statement(s). Again, I have no idea how the VB interface method that is using. The VB Developer reported to me the bug and gave me the value collected from his VB interface. The only thing could fix the bug is using his provide value to adjust my sp handling. I know it is not a good way but it is the organization structure. What can I do?
AC
August 26, 2003 at 1:18 am
If any SQL statement would be valid....
Would an Exec or sp_executesql be valid as well.......
August 26, 2003 at 4:59 am
In principal yes, if the quotes are handled correctly
Select count(*)
from sysobjects
where name like 's%'
go
Exec ('Select count(*)
from sysobjects
where name like ''s%''')
Viewing 15 posts - 16 through 30 (of 30 total)
You must be logged in to reply to this topic. Login to reply