How do I create a new column or field (idnew) in an existing Access database (resultdb) using PHP PDO?.
You are able to create new columns with the query function as well as the prepared statement function. Whitch one you should use depends on what you want to do with it.
Example 1
$pdo->query('ALTER TABLE resultdb ADD idnew INT(11)');
Example 2
function addColumn($column, $type)
{
$query = $pdo->prepare('ALTER TABLE resultdb ADD :column :type');
$query->execute(array(':column' => $column, ':type' => $type));
}
addColumn('idnew', 'INT(11)');
Be careful that you are not destroying any functions built in you website by doing this.
Related
I'm trying to insert an array of data into a table in database but an error said Array to string conversion error
This is the post function in my controller, first i post an array of data. The values of the array will be the names, and numbers, they are not id. The id is only kodejdwl. This will be pass to my model
function index_post() {
$data = array(
'kodejdwl' => $this->post('kodejdwl'),
'tahun_akad' => $this->post('kode_tahun_akad'),
'semester' => $this->post('semester'),
'mk' => $this->post('mk'),
'ruangan' => $this->post('ruangan'),
'nama_dosen' => $this->post('nama_dosen'),
'namakelas' => $this->post('nama_kelas'),
'jam_mulai' => $this->post('jam_mulai'),
'jam_selesai' => $this->post('jam_selesai'),
);
}
After the data from above code is passed to the model. I created some new variables which are the id of each the name of the value in the array data. e.g if the value of data['mk'] is Website then the id will be 1 and that id will be stored in variable $kodemk and i do it to each value in the data. Then i created new_data which stores array of the id's which i previously made. Then i insert that array into one table in my database. I thought it would be fine but it said Array to string conversion error. What should i do so i could insert that array into the table in my database?
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->result();
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->result();
$this->db->flush_cache();
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->result();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->result();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->result();
$this->db->flush_cache();
$this->db->select('kode_jam');
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->result();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id,
'matakuliah_kodemk' => $kode_mk,
'ruangan_namaruang' => $ruangan,
'staff_nip' => $nip_dosen,
'kelas_kodeklas' => $kodeklas,
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
You probably want to use row() instead of result() because it'll contain only one result that you want. If you want to use result() and store multiple values then you'll have to use implode to concatenate them and store it as a string.
I've written a possible solution for your problem; Some things were missing, so I've mentioned them in the comments. See if this helps you.
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->row(); // use row here
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->row();
$this->db->flush_cache();
// remove your_ruangan_column with your desired column name
$this->db->select('your_ruangan_column');
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->row();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->row();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->row();
$this->db->flush_cache();
// Not sure where this ↓↓ is being used but you can use it the same way as others
$this->db->select('kode_jam');
// duplicate variable name here ↓↓ (fix this)
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->row();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id->thn_akad_id, // {$tahunakad_id} consists an object with the key {thn_akad_id}-- table_column_name
'matakuliah_kodemk' => $kode_mk->kodemk, // ...
'ruangan_namaruang' => $ruangan->your_ruangan_column, // ...
'staff_nip' => $nip_dosen->nip, // ...
'kelas_kodeklas' => $kodeklas->kodeklas // ...
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
Your are making a total of 7 separate trips to the database. Best practice recommends that you always minimize your trips to the database for best performance. The truth is that your task can be performed in a single trip to the database so long as you set up the correct INSERT query with SELECT subqueries.
I don't know what your non-English words are, so I will use generalized terms in my demo (I've tested this successfully in my own CI project). I am also going to reduce the total subqueries to 3 to reduce the redundance in my snippet.
$value1 = $this->db->select('columnA')->where('cond1', $val1)->get_compiled_select('childTableA');
$value2 = $this->db->select('columnB')->where('cond2', $val2)->get_compiled_select('childTableB');
$value3 = $this->db->select('columnC')->where('cond3', $val3)->get_compiled_select('childTableC');
return (int)$this->$db->query(
"INSERT INTO parentTable
(column1, column2, column1)
VALUES (
($value1),
($value2),
($value3)
)"
);
// to mirror your affected rows return... 1 will be returned on successful insert, or 0 on failure
Granted this isn't using the ActiveRecord technique to form the complete INSERT query, but this is because CI doesn't allow subqueries in the VALUES portion (say, if you were to use the set() method). I am guessing this is because different databases use differing syntax to form these kinds of INSERTs -- I don't know.
The bottom line is, so long as you are fetching a single column value from a single row on each of these sub-SELECTs, this single query will run faster and with far less code bloat than running N number of individual queries. Because all of the variables involved are injected into the sql string using get_compiled_select() the stability/security integrity should be the same.
I have a datase table with a list of books. Below is my sql statement:
SELECT `Book`.`id` , `Book`.`name` , `Book`.`isbn` , `Book`.`quantity_in_stock` , `Book`.`price` , (`Book`.`quantity_in_stock` * `Book`.`price`) AS `sales`, concat(`Author`.`name`, ' ', `Author`.`surname`) AS `author`
FROM `books` AS `Book`
LEFT JOIN authors AS `Author`
ON ( `Book`.`author_id` = `Author`.`id` )
WHERE (`Book`.`quantity_in_stock` * `Book`.`price`) > 5000.00
The query works fine and the workflow works fine too. However, I am wanting to access this through an API and make the 5000.00 value configurable through a variable bar.
Question is how do I make this possible such that when I call my API with my endpoint below it works?
https://domain.flowgear.io/5000booklist/{sales_value}
What I want is to be able to re-use my workflow via an API and just pass a sales value I want to query the table against. Sales value can be 2000 or 5000 depending on what I want to achieve.
Add a variable bar and add a property to it called "salesValue"
In the workflow detail pane, provide this url: "/booklist/{salesValue}" - the value in braces must match the name of the property in the variable bar
Add a Formatter, put your SQL template including "WHERE (Book.quantity_in_stock * Book.price) > {salesValue}" in the Expression property then add a custom field called salesValue and pin that from the variable bar salesValue property. Set Escaping to SQL.
Take the output of the Formatter and plug that into the SQL Query property of a SQL Query Connector.
Add another variable bar, and add the special properties FgResponseBody and FgResponseContentType
Pin the SQL result to FgResponseBody and set FgResponseContentType to 'text/xml'
If you want to return JSON, convert the result from the SQL Query to JSON using JSON Convert and then pin that to FgResponseBody and set FgResponseContentType to 'application/json'
#sanjay I will try to give you an overview of what I did back then when I was experimenting with Flowgear through PHP following instructions from here.
I am not sure if you are also invoking the Flowgear REST API through PHP or any other language but regardless I presume logic should remain the same.
What I did was to wrap the PHP CURL sample code in a class so that I can be able to reuse it. Below is a code I wrote for a simple select query:
<?php
//Require the FlowgearConnect class
require_once '/path/to/flowgear_class_with_api_call.php';
try{
$workflow = new FlowgearConnect(return include 'endpoints.php');
$serial = $_POST['serial'];
$clientId = $_POST['client_id'];
//Get the results
$sql = '';
if(empty($serial)){
$conditions = sprintf(' `a`.`client_id` = %s AND `a`.`serial` > -1 ORDER BY `a`.`serial` ASC', $clientId);
}else{
$conditions = ' `a`.`serial` = ' . $serial;
}
/**
In your workflow you will most probably have a VARIABLE BAR that holds your request parameters which is what $conditions speaks to.
*/
$conditions = array('conditions' => $conditions);
$results = $workflow->getResults('orders', 'orders', $conditions);
}catch(catch any exceptions thrown by the API here){
//Log the exceptions here or do whatever
}
The listing above should be self explanatory. Below I will show you the functions I have made use of from my FlowgearConnect class. This is not a standard way as you may configure your code differently to suite your needs.
//FlowgearConnect constructor
class FlowgearConnect
{
protetced $endpoints = [];
protected $domain = "https://your-domain.flowgear.io";
public function __construct(array $endpoints)
{
$this->endpoints = $endpoints;
}
public function getResults($model, $workflow, $options= array())
{
$endpoint = $this->getEndpoint($model, $workflow);
$results = array();
if(!empty($endpoint)){
$results = FlowgearInvoke::run($authOpts, $endpoint, $options, array('timeout' => 30));
}
return $results;
}
....
}
The enpoints.php file, as mentioned before, just returns an array of configured endpoints and/or worflow names from within flowgear console. Below is a excerpt of how mine looked like:
return array(
'orders' => array(
'shipped_orders' => '/shipped_orders',
//etc
),
'items' => array(
'your_model' => '/workflow_name_from_flowgear_console',
),
);
This is just a basic select query with Flowgear's REST API using PHP. If you are lucky you should get your records the way you have configured your response body for your workflow.
Below is a typical testing of a workflow and what you should get back in your API.
I advice you to first create your workflows on your flowgear console and make sure that the produce the desired output and the extract the parts that you want changed no your query, move them to a variable bar for your request and have them injected at run-time based on what you looking to achieve. This explanation can be substituted for other operations such as update and/or delete. Best thing is to understand flowgear first and make sure that you can have everything working there before attempting to create a restful interactive application.
Caution: It's over a year that I have since worked with this platform so you might find errors in this but I am hoping that it will lead you to finding a solution for your problem. If not then perhaps you can create a repo and have me check it out to see how you are configuring everything.
I would like to insert an array into a MYSQL database, preferably using Yii's active record.
For example, I have a an array:
User = array(
fname => "Joe"
lname => "Schmidt"
)
with a User table in my database with columns id, fname and lname. One of the options is creating an object and doing:
$user = new User;
$user->fname = User['fname'];
$user->lname = User['lname'];
$user->save();
However, this seems like so much code for such common functionality. Is there a way to insert an array into the database where array keys match corresponding columns without me writing my own function or doing some SQL query hack? Ideally it uses the already present Active record of Yii.
What you want to do is handled by the framework itself.
You can mass assign like:
$user->attributes=$_POST['User'];
Read more about Mass Assignment
I have never worked with Yii before, so I can't offer a solution using that, but you can serialize the array and store it in the single cell in your database, like so:
$user = array("fname" => "Joe", "lname" => "Schmidt");
$serialized = serialize($user);
//Store the $serialized variable in the database
When you are ready to access it:
//Get your data from the database
$unserialized = unserialize($usersFromDB);
$fname = $unserialized['fname']; //Joe
Hope that helps.
the function is pretty straightforward, try this:
function insert($table, $fields_values = array())
{
$q1 = join(",", array_keys($fields_values));
$q2 = "'".join("','", array_values($fields_values))."'";
$query = "INSERT INTO $table($q1) VALUES($q2)";
// do your DB insert here
}
The main trick is the array to query conversion using join and array_keys / array_values.
Depending the amount of data in array you can write you own function e.g
a) check this backUpdate , modify it to insert /remove render view option
b) Follow this thread
c) Possible traps when inserting multiple records
d) check this associated SOQ
If you know what you are doing its easy to do , you just need to take care of
validations
records exists in associated tables ( if there is FKey involved )
option d). will be a posssible answer if you have simple inserts ( with no associated tables)
I am very new to stored procedures and the PDO library so please take it easy on me. I am trying to execute a stored procedure using a PDO function and retrieve the recordsets along with the output parameters. Which function should I use and what parameters are necessary?
If I want to execute basic statements using the function like the following example, what PDO method should I use? e.g.
$mssql = new mssql;
$mssql->sql('stored_procedure()');
$mssql->sql('SELECT * FROM [test]');
I want the function to return the correct results dependant on the statement type. Is this going to be possible?
UPDATE
Just in case I didnt make it very clear, the 'mssql' class uses the PDO class to execute queries. At the moment I am using:
$PDO->prepare();
$PDO->exec();
After researching around the internet, I found it is in fact very simple using the PDO prepare, bindParam and execute methods.
An example of a store procedure using my class:
$mssql->bind_params = array(
'BatchNum' => array(
'value' => 'SS000008'
),
'RecCount' => array(
'value' => 0,
'type' => PDO::PARAM_INT,
'length' => 8
)
);
$mssql->sql("{CALL sp_Batch_Sales(#paramOne=:paramOne,#paramTwo=:paramTwo)}");
This is converted to:
$query = $PDO->prepare({CALL sp_Batch_Sales(#paramOne=:paramOne,#paramTwo=:paramTwo)});
$query->bindParam(':paramOne',$returned_parameters['paramOne']);
$query->bindParam(':paramTwo',$returned_parameters['paramTwo'],PDO::PARAM_INT,8);
$query->execute();
The recordsets can then be retrieved using:
do{
// Get the results
$results = $query->fetchAll(PDO::FETCH_ASSOC);
// Only place the results into the array if they exist
if(!empty($results)){
$data[$i]['results'] = $results;
}
// Set the number of rows in the result array
$data[$i]['rows'] = $query->rowCount();
// Increment i
$i++;
}while($query->nextRowset());
And the input and output parameters can be retrieved using the array:
$returned_parameters
I hope this helps
I am trying to implement a very simple search function with PHP in symfony.
Basically I have a form that posts a query and I want to retrieve the items in the database that match the query.
If I have a User table with columns first_name and last_name, I want to be able to retrieve all items that contain a query. For example, if I submit 'a', I will get all names that have an 'a' in them:
Bat Man
Black Beard
Adam West
Mister A
So I know I can get all objects in the table whose first names contain 'a' by specifying criteria:
$c = new Criteria();
$c->add(UserPeer::FIRST_NAME, '%a%', Criteria::LIKE);
$users = UserPeer::doSelect($c);
Is there a way I can pass a variable like $query in the add() function? Can I acquire $query via a form and then pass it as a variable in the add function and get all the objects that contain it? Am I even going about this the right way?
On your form create an input with the id 'query'
<label for="query">Query:</label>
<?php echo input_tag('query') ?>
In the action get the parameter IF the form has been submitted
then pass it into your criteria
if($this->getRequest()->getMethod() == sfRequest::POST)
{
$query = $this->getRequestParameter('query');
$c = new Criteria();
$c->add(UserPeer::FIRST_NAME, '%'.$query.'%', Criteria::LIKE);
$users = UserPeer::doSelect($c);
}