0

Im writing PHP scripts for using with my mySQL database. The only problem i have is binding variables for drop table/ create table and so on.

    $stmt = $link->prepare("DROP TABLE ?");
    $stmt->bind_param('s','testing'); 
    $stmt->execute();

is not working. I tried also:

SELECT * FROM (SELECT MAX(name) from profiles where name='testing') <- is working
DROP TABLE (SELECT MAX(name) from profiles where name='testing') <- dont work

3 Answers 3

2

Binding a parameter is not the same as just replacing a portion of the string : you cannot just bind anything you want.

In this case : you cannot use a bound parameter for a table name -- you'll have to use string concatenations to build your query, instead of using a prepared statement.


As a reference, quoting PREPARE Syntax :

Parameter markers can be used only where data values should appear, not for SQL keywords, identifiers, and so forth.

Sign up to request clarification or add additional context in comments.

Comments

1

As far as I know, you can only bind to a parameter, not to any part of a query you want. You're essentially telling the database "hey, I'm going to pass you a value here, and I want you to do your magic to make sure it doesn't overstep its bounds". Things like table names or field names aren't values, they're part of the table structure itself.

In this case, you'll have to just use a use a simple $query = "DROP TABLE " . $table;. It should be easy enough to check against a list of known tables to ensure you're not injecting anything harmful. Anything that makes DDL changes shouldn't be taking input from the user anyway, as far as I'm concerned. These sorts of changes can be based on user input, but the actual construction of the query should be really well known and shouldn't need outside data to construct.

Also, I'm not really sure what you're trying to do with this query:

DROP TABLE (SELECT MAX(name) from profiles where name='testing');

It looks like you might be trying to delete a record, but that's entirely the wrong syntax for that. If you're trying to drop a table whose name comes from the result of another query, I really don't think you can do that either. I'm 99% sure that DROP TABLE expects only a literal table name value.

2 Comments

It might be bad design. I had the 2 tables - images and profiles. Each image could be assigned to one or more profiles. Since i will have ~1000 images and only ~20 profiles, for optimalizaation purpose i didnt want to create table imagexprofile - where i would bind both ID together ( image1 goes to profile 1, image1 goes to profile3, image2 goes to profile3 etc). But i think i will return to that idea and use indexes instead.
@Thomas There's nothing wrong with creating a ProfileImages table (personal preference for the name, as the profile is the dominant table in this relationship). I'm assuming this is a many-to-many relationship (i.e. a single image can be used on multiple profiles, and a single profile can have multiple images)? The way you describe it, it sort of sounds like a profile would only have a single image. If that's the case, then you should just have a foreign key in your profiles table linking to the id field of your images table.
0

Are you sure you want to drop tables dynamically?
It is extremely unusual.

It seems you have wrong database design.
And now you faced a consequence.

It seems you should have one table users and delete rows from it, not tables.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.