how to create a table using createCommand in Yii?
I've followed the instructions in the http://www.yiiframework.com/doc/api/1.1/CDbCommand but I am still confused. Can you give an example of creating a table using createCommand in yii.
thank you
Assuming you've named your database connection string db (in protected/config/main.php) as follows,
'components'=>array(
'db'=>array(
),
),
you should be able to create a table using the following command:
$sqlQuery = "CREATE TABLE IF NOT EXISTS pet (name VARCHAR(20), owner VARCHAR(20))";
$sqlCommand = Yii::app()->db->createCommand($sqlQuery);
$sqlCommand->execute();
You should also be able to replace the first line with any SQL statement and execute it successfully. If you want to query for data, you will need to use queryRow, queryColumn, or queryScalar (as defined in the documentation).
Hope this helps!
I use this code and sucess..
Yii::app()->db->createCommand("CREATE TABLE {$nama_data}(id serial, {$list_field}, x text,y text,wkt text, the_geom geometry,PRIMARY KEY(id));")->query();
Related
How can i add index to any field in database using codeigniter migration.?
I have tried with alter query but i didn't find array key for indexing to pass in alter query?
$fields = array('photo_id' =>
array('type' => 'INT',
'constraint'=>11,
'after'=>'photo_req_id',`enter code here`
'null'=>false));
And i also try to find on codeigniter documentation but not mention anything about indexing.
Guys please help to set indexing by using codeigniter migration method.
Indexing is done by using the add_key function documented here.
To create a PRIMARY KEY index on photo_id
$this->dbforge->add_key('photo_id', TRUE);
To create a secondary index on photo_id
$this->dbforge->add_key('photo_id');
There is no such interface until CI 3 and the under development CI 4.
You can use
$this->db->query('CREATE INDEX your_index_name ON your_table_name (your_column_name);');
I am developing an application for fun, and I am purposefully NOT using any frameworks aside from mustache for PHP and JS, etc on either the client or server side of the modest application.
Each view has a table which holds all data used for each one. I wish to execute a query that selects each column in the table and makes it available to my mustache template.
I do NOT want to change methods in order to access any particular column at runtime. fetchAll gives me a ton of null fields in the data returned that I do not want while fetch() gives me a nice JSON structure containing all of the proper data aside from a column containing more than one row of data only shows for the first row/instance.
Here is my PHP method:
public function get_view($view_name , $out_type = "raw"){
// Col names may vary from view table to view table
$statement = $this->prep_sql("SELECT * FROM `$view_name`");
$statement->execute(array());
$view_data = $statement->fetch(); // I know fetchAll will work for arrays but how then will my mustache template bind to data returned from columns with more than one row?
return (strtoupper($out_type) === "JSON" ? json_encode($view_data) : $view_data);
}
What I want is to ignore any fields with null or empty as if they do not exist and form an array with columns in the database with multiple rows of data. I also realize that using fetch for single instances like a page title and fetchAll would work for multiple rows however I want to eliminate this.
In order for the templates to bind correctly the data output must look similar to:
{
module_name: 'main',
module_title: 'Main',
module_images: ['http://...', 'http://...', 'http://...'],
module_scripts: ['http://...','http://...','http://...',]
}
Instead with fetchAll I get
[{
module_name: 'main',
module_title: 'Main',
module_images: 'http://...', // 1
module_scripts: 'http://...' // 1
}, {
module_name: null,
module_title: null,
module_images: 'http://..', // 2
module_scripts: 'http://..' // 2
}];
I am aware SELECT * is not a traditional way to select all of your view data however the number of cols in each view table will be less than 100 max and no tables besides view tables will be accessed using a wildcard select. That said along with the dynamic col names from view to view mean ALOT less code to write. I hope that this doesnt offend anybody :)
Thank you all kindly for the help.
Is this what you are after??
CREATE TABLE view_data_main (
module_name VARCHAR(30),
module_title VARCHAR(30),
module_images VARCHAR(30),
module_scripts VARCHAR(30)
)
INSERT INTO `view_data_main` (module_name,module_title,module_images,module_scripts) VALUES
('welcome','main','http://www.test.com','http://www.test2.com'),
(NULL,NULL,'http://www.test.com','http://www.test2.com'),
(NULL,NULL,'http://www.test.com','http://www.test2.com')
SELECT module_name,module_title,GROUP_CONCAT(module_images),GROUP_CONCAT(module_scripts)
FROM `view_data_main`
WHERE module_images IS NOT NULL AND module_scripts IS NOT NULL
GROUP BY CONCAT(module_images,',',module_scripts)
Having re-read the question I don't think the subquery is necessary unless I'm missing something?
I am building a Wordpress site and it is connected to a MySQL database. I am using the wordpress class wpdb (https://codex.wordpress.org/Class_Reference/wpdb) to interact with the database. With that class, I am able to query TABLES of my database, but not Views.
I need to be able to select Views of my database. Is this something that is not allowed with wpdb, or is my code just wrong? Is there a way to query views the same way I can query tables using wpdb?
I have tried using the query function, as well as treating a view the same way I treat a table, but it does not work. It returns empty.
Query method:
$test = $mydb->query(
$mydb->prepare(
"
SELECT name FROM $mydb->$view_name
WHERE id = 1"
)
);
echo $test; //returns empty; should return a name
Table method:
$test = $mydb->get_var(
"select name from $view_name WHERE id = 1"
);
echo $test; //returns empty; should return a name
Any suggestions? Am I able to connect to my database using something other than $wpdb (does Wordpress allow that?).
name seems to be a reserved word in MySQL (reference). Try surrounding it with back-ticks (`) like this:
SELECT `name` FROM ...
You should be seeing some errors, do you keep an eye on the logs? Also, when you have doubts in your queries, you can simply copy the raw query and execute it into phpMyAdmin or whatever tool you are using to access your database manually
I have model A and model B which lie in two different databases.
Now I have a pivot_table called a_bs in the same database as model A.
I've setup the belongsToMany relatinoship like this in model A
public function bs()
{
return $this->belongsToMany('B', 'a_bs', 'a_id', 'b_id');
}
When I try to access this relationship like so:
$a = A::find($id);
print_r($a->bs->lists('id'));
I get an error that my pivot table doesn't exist in model B's database. Which is obviously correct since the pivot table is in model A's database. How can I let Laravel know that?
Do not suggest to put the pivot table in model B's database
Very simply:
public function bs()
{
$database = $this->getConnection()->getDatabaseName();
return $this->belongsToMany('B', "$database.a_bs", 'a_id', 'b_id');
}
I'm obtaining the database name dynamically because my connection is configured based off an environment variable. Laravel seems to assume the pivot table to exist in the same database as the target relation, so this will force it to look instead to the database corresponding to the model that this method is in, your 'A' realm.
If you're not worried about SQLite databases, i.e. in the scope of a unit-test, that's all you need. But if you are, keep reading.
Firstly, the previous example isn't sufficient on its own. The value of $database would end up being a file-path, so you need to alias it to something that won't break an SQL statement, and make it accessible to the current connection. "ATTACH DATABASE '$database' AS $name" is how you do that:
public function bs()
{
$database = $this->getConnection()->getDatabaseName();
if (is_file($database)) {
$connection = app('B')->getConnection()->getName();
$name = $this->getConnection()->getName();
\Illuminate\Support\Facades\DB::connection($connection)->statement("ATTACH DATABASE '$database' AS $name");
$database = $name;
}
return $this->belongsToMany('B', "$database.a_bs", 'a_id', 'b_id');
}
Warning: Transactions muck this up: If the current connection is using transactions, the ATTACH DATABASE statement will fail. You can use transactions on it after executing that statement though.
Whereas, if the related connection uses transactions, the resulting data will be silently rendered invisible to the current one. This drove me nuts for longer than I'd care to admit, because my queries ran without error, but kept coming up empty. It seems only data truly written to the attached database is actually accessible to the one it's attached to.
So, after being forced to write to your attached database, you may still want your test to clean up after itself. A simple solution there would be to just use $this->artisan('migrate:rollback', ['--database' => $attachedConnectionName]);. But if you have multiple tests that need the same tables, this is not very efficient, as it forces them to have to rebuild them each time.
A better option would be to truncate the tables, but leave their structure in tact:
//Get all tables within the attached database
collect(DB::connection($database)->select("SELECT name FROM sqlite_master WHERE type = 'table'"))->each(function ($table) use ($name) {
//Clear all entries for the table
DB::connection($database)->delete("DELETE FROM '$table->name'");
//Reset any auto-incremented index value
DB::connection($database)->delete("DELETE FROM sqlite_sequence WHERE name = '$table->name'");
});
}
This will wipe all data from that connection, but there's no reason you couldn't apply some kind filter to that however you see fit. Alternatively, you could take advantage of the fact that SQLite DBs are easily-accessible files, and just copy the attached one to a temp file, and use it to overwrite the source after the test is done executing. The result would be functionally identical to a transaction.
You can set the database of the table in the model class:
protected $table = 'A.a_s';
And You have to use singular form when create a pivot table.
/app/model/A.php
class A extends Eloquent {
// Set table name (plural) with database name
protected $table = 'A.a_s';
// Many to many relation
public function b_s() {
return $this->belongsToMany('B');
}
}
/app/model/B.php
class B extends Eloquent {
// Set table name (plural) with database name
protected $table = 'B.b_s';
}
Query
print_r(A::with('b_s')->where('id', 1)->get()->toArray());
MySQL
CREATE TABLE `A`.`a_s` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
);
CREATE TABLE `B`.`b_s` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
);
CREATE TABLE `A`.`a_b` (
`a_id` int(10) unsigned NOT NULL,
`b_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`a_id`,`b_id`)
) ENGINE=InnoDB;
INSERT INTO A.a_s VALUES (NULL);
INSERT INTO A.a_s VALUES (NULL);
INSERT INTO B.b_s VALUES (NULL);
INSERT INTO A.a_b VALUES (1,1);
INSERT INTO A.a_b VALUES (1,2);
If the databases/schemas are on the same host server like #NiRR said just do this to override the default schema of the second connection:
return $this->belongsToMany('B', 'real-schema-name.a_bs');
or alternatively
return $this->belongsToMany('A', 'real-schema-name.a_bs');
Depending on which model (A or B) is defined with the connection that isn't using the default schema.
Remember that it's impossible to do a join query that spans across two servers; which server is it going to get executed on? Each is missing some of the needed data needed to preform the request.
This is only possible if the two databases are on the same connection (server).
Its not possible to do this on two different connections (servers) since you'll need all three tables on a single server that will perform the join command.
Explicitly setting or defining the connection for both models works just fine.
protected $connection = 'connection1'; //inside model A
protected $connection = 'connection2'; //inside model B
EDIT
When Laravel is fetching a model from the DB, provided a database/connection has been defined (as a property) within the model, Laravel will use the database name for that connection when constructing the SQL. So when working with multiple connections, it is best to define the connection for every model.
Hopefully a simple question.
error_reporting(E_ALL);
ini_set('display_errors', '1');
$c = oci_connect('whatmyusrnameis', 'whatmypwdis', 'host');
if ($c) {
echo 'connection';
}
$s = oci_parse($c, 'select * from mantis_bug_table');
oci_execute($s);
The following results in
Warning oci_execute(): ORA-00942: table or view does not exist
but the connection doesn't result in any errors and the DB table does exist and it is not empty.
Any ideas??? Thank you :).
Typically this has one of four possible problems
You're not connecting to the database you think you are (probably not the case)
You don't have permission to the table (See Justin Cave's answer regarding Grant)
You may need to add the owner to the table name e.g. select * from DB_USER.mantis_bug_table (See Justin Cave's answer regarding SYNONYMs if you don't want qualify the tablename)
The table really doesn't exist perhaps a spelling error
You can diagnose this by running the following
SELECT * FROM ALL_TABLES WHERE UPPER(table_name) = 'MANTIS_BUG_TABLE'
What Oracle user owns the table?
Does the Oracle user that your PHP script connects as have access to this table?
Is there a public or private synonym for the MANTIS_BUG_TABLE table?
If the table is owned by some other user, you could try fully qualifying the table name
$s = oci_parse($c, 'select * from owner_of_table.mantis_bug_table');
If the user your PHP script is using doesn't have access to the table, you'll need a DBA or the owner of the table to
GRANT SELECT ON owner_of_table.mantis_bug_table
TO whatmyusernameis;
If you have access to the table and fully qualifying the table name works but you don't want to have to fully qualify the table name every time, you can create a synonym
CREATE [PUBLIC] SYNONYM mantis_bug_table
FOR owner_of_table.mantis_bug_table
A public synonym allows all users with access to the table to reference it without using a fully qualified name. A private synonym allows just the owner of the synonym (i.e. whatmyusernameis) to reference the table without a fully qualified table name.
You should point scheme in connection string like:
oci_connect('whatmyusrnameis', 'whatmypwdis', 'host/**YOUR_DB**');
Look at http://www.php.net/manual/en/function.oci-connect.php in section connection_string