I am working on a php code where I insert into two tables and want to grab the id from the first table I inserted into, right now I am getting this error: Call to undefined function sqlsrv_field(). I am trying to grab the routine_id from the table routines.
Code:
date_default_timezone_set('Europe/Oslo');
$date = strftime ('%Y-%m-%d');
$time = strftime('%H:%M:%S');
$value = $_GET['Temp'];
$conn = sqlsrv_connect('BILAL' , $conn_array);
$sql = "Insert into routines (date, time, value, emp_id) values ('$date', '$time', '$value', (SELECT id FROM emps WHERE user_name='Arduino'))";
if ( sqlsrv_begin_transaction( $conn ) === false ) {
die( print_r( sqlsrv_errors(), true ));
}
$query = sqlsrv_query( $conn, $sql);
if( $query === false ) {
die( print_r( sqlsrv_errors(), true));
}
sqlsrv_next_result($query);
sqlsrv_fetch($query);
$id = sqlsrv_field($query,0);
$sql2 = "Insert into measure_routines (routine_id, measure_id, pool_id) values ('$id', (Select id from measurements where title='A_Auto_Temperatur'), 1 )";
$stmt = sqlsrv_query( $conn, $sql2);
if( $stmt === false ) {
die( print_r( sqlsrv_errors(), true));
}
There is no function called sqlsrv_field(). Instead, use sqlsrv_get_field():
...
sqlsrv_next_result($query);
bool fetchStatus = sqlsrv_fetch($query);
if(fetchStatus === false) {
die( print_r( sqlsrv_errors(), true));
}
if(fetchStatus === null) {
// Some work when there are no results in the result set
} else {
$id = sqlsrv_get_field($query, 0);
}
...
This should solve your problem basically. However your code is vulnerable to SQL injection. Instead of giving values directly into the sql query, consider using prepared statements.
There are many articles about that, here is one I found in quick search:
What's the Right Way to Prevent SQL Injection in PHP Scripts?
Try this:
function lastId($queryID) {
sqlsrv_next_result($queryID);
sqlsrv_fetch($queryID);
return sqlsrv_get_field($queryID, 0);
}
$lastInsertedId = lastId($stmt);
Related
I want to update a table where column user_id has values, stored in an array, but I get this error:
Array ( [0] => Array ( [0] => 42S22 [SQLSTATE] => 42S22 [1] => 207
[code] => 207 [2] => [Microsoft][ODBC Driver 17 for SQL Server][SQL
Server]Invalid column name 'Array'. [message] => [Microsoft][ODBC
Driver 17 for SQL Server][SQL Server]Invalid column name 'Array'. ) )
This is my code:
$sql = "
SELECT usuario_id
FROM control_asistencias
WHERE
ano=".$ano." and
mes=".$mes." and
dia".$dia."='T' and
comida_habitual ='T'
";
$stmt = sqlsrv_query( $conn, $sql);
if( $stmt === false ) {
die( print_r( sqlsrv_errors(), true) );
}
$usuarios_comida_habitual = array();
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
array_push($usuarios_comida_habitual,$row['usuario_id']);
}
// Una vez que tenemos los usuarios Que han fichado para ese dia hacemos un Update
$sql_update = "
UPDATE VLD_PRESENCIA
SET VLD_PRESENCIA_DIA".$dia." = 'T'
WHERE
VLD_PRESENCIA_CODUSUARIO IN (".$usuarios_comida_habitual.") AND
VLD_PRESENCIA_COMIDA_HABITUAL = 'T'
";
$stmt2 = sqlsrv_query( $conn2, $sql_update);
if( $stmt2 === false ) {
die( print_r( sqlsrv_errors(), true) );
}
else
{
echo 'eureka';
}
Is it possible that the way the array was passed is wrong? Or is it possible to put the condition that I want to implement what userid should be in that array?
I found this
array_walk($usuarios_comida_habitual , 'intval');
$ids = implode(',', $usuarios_comida_habitual);
i Do this before generating $sql_update
Consider a single SQL query without any loop since IN supports subqueries. And since connections run across different servers, consider OPENROWSET for ad hoc queries. Adjust ODBC connection string parameters and [database].[schema] identifiers accordingly. (Note: default schema is dbo).
$sql = "UPDATE VLD_PRESENCIA
SET VLD_PRESENCIA_DIA".$dia." = 'T'
WHERE VLD_PRESENCIA_CODUSUARIO
IN (SELECT sub.usuario_id
FROM OPENROWSET('SQLNCLI',
'DRIVER={SQL Server};SERVER=ServerName;UID=userID;PWD=password',
'SELECT * FROM [database].[schema].control_asistencias') sub
WHERE sub.ano = ?
AND sub.mes = ?
AND sub.dia".$dia." = 'T'
AND sub.comida_habitual = 'T')
AND VLD_PRESENCIA_COMIDA_HABITUAL = 'T'";
$prms = array($ano, $mes);
$stmt = sqlsrv_query($conn, $sql, $prms);
if( $stmt === false ) {
die( print_r( sqlsrv_errors(), true));
}
Although using an array for the IN clause has already a similar answer, you may try to use the sqlsrv_prepare()\sqlsrv_execute() combination to prepare a statement and execute it multiple times. But in both cases you need to consider the following:
Always try to use parameters in your statements to prevent possible SQL injection issues.
When the column name is used dynamically (possible wrong design), check the genarated name using sys.columns system catalog view to prevent possible SQL injection issues.
Note, the reason for your error is the fact, that you are trying to build an SQL statement concatenating a string literal and a PHP array.
The following example, based on your code and using parameterized queries, is a possible solution to your problem:
<?php
// SELECT statement
$sql = "
SELECT usuario_id
FROM control_asistencias
WHERE ano = ? AND mes = ? AND dia".$dia." = 'T' AND comida_habitual = 'T'
";
$params = array($ano, $mes);
$stmt = sqlsrv_query($conn, $sql, $params);
if ( $stmt === false ) {
die( print_r( sqlsrv_errors(), true) );
}
$usuarios_comida_habitual = array();
while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$usuarios_comida_habitual[] = $row['usuario_id'];
}
// Multiple UPDATE statements
$sql = "
UPDATE VLD_PRESENCIA
SET VLD_PRESENCIA_DIA".$dia." = 'T'
WHERE
VLD_PRESENCIA_CODUSUARIO = ? AND
VLD_PRESENCIA_COMIDA_HABITUAL = 'T'
";
$usuario = 0;
$params2 = array(&$usuario);
$stmt2 = sqlsrv_prepare($conn2, $sql, $params2);
if ( $stmt2 === false ) {
die( print_r( sqlsrv_errors(), true) );
}
foreach ($usuarios_comida_habitual as $usuario) {
if (sqlsrv_execute($stmt2) === false ) {
die( print_r( sqlsrv_errors(), true) );
} else {
echo 'eureka';
}
}
?>
If you want to execute a single UPDATE statement, the following approach is an option, but again with parameterized statement:
<?php
// SELECT statement
$sql = "
SELECT usuario_id
FROM control_asistencias
WHERE ano = ? AND mes = ? AND dia".$dia." = 'T' AND comida_habitual = 'T'
";
$params = array($ano, $mes);
$stmt = sqlsrv_query($conn, $sql, $params);
if ( $stmt === false ) {
die( print_r( sqlsrv_errors(), true) );
}
$usuarios_comida_habitual = array();
while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$usuarios_comida_habitual[] = $row['usuario_id'];
}
// Single UPDATE statement
$usuarios_placeholders = substr(str_repeat(',?', count($usuarios_comida_habitual)), 1);
$sql = "
UPDATE VLD_PRESENCIA
SET VLD_PRESENCIA_DIA".$dia." = 'T'
WHERE
VLD_PRESENCIA_CODUSUARIO IN (".$usuarios_placeholders.") AND
VLD_PRESENCIA_COMIDA_HABITUAL = 'T'
";
$stmt2 = sqlsrv_query($conn2, $sql, $usuarios_comida_habitual);
if ( $stmt2 === false ) {
die( print_r( sqlsrv_errors(), true) );
} else {
echo 'eureka';
}
?>
In MySQL we used the mysqli_stmt_bind_param to bind parameters.
What should I use to bind parameters in sqlsrv?
$sql = "SELECT * FROM dbo.[user] WHERE username = ? and password = ?";
$stmt = sqlsrv_prepare($conn, $sql, $params);
if($stmt === false){
die( print_r( sqlsrv_errors(), true));
}
How can I bind this parameters? This is a php file and I need to bind them without pdo.
You don't explicitly bind the parameters by using another function, you do it when preparing the statement.
See the example from the manual.
$sql = "UPDATE Table_1
SET OrderQty = ?
WHERE SalesOrderID = ?";
// Initialize parameters and prepare the statement.
// Variables $qty and $id are bound to the statement, $stmt.
$qty = 0; $id = 0;
$stmt = sqlsrv_prepare( $conn, $sql, array( &$qty, &$id));
if( !$stmt ) {
die( print_r( sqlsrv_errors(), true));
}
// Set up the SalesOrderDetailID and OrderQty information.
// This array maps the order ID to order quantity in key=>value pairs.
$orders = array( 1=>10, 2=>20, 3=>30);
// Execute the statement for each order.
foreach( $orders as $id => $qty) {
// Because $id and $qty are bound to $stmt1, their updated
// values are used with each execution of the statement.
if( sqlsrv_execute( $stmt ) === false ) {
die( print_r( sqlsrv_errors(), true));
}
}
We would like to query our database and sample records based on a particular user's department.
Given the app design, the only way I know to do this is to filter the query by using dept's session variable.
The code below is not working.
Data gets returned if I comment out the session variable.
Nothing is getting retrieved with the session variable as filter.
Any ideas what I am doing wrong?
Is the session variable route the wrong approach?
Thanks in advance for help.
//Start your session
session_start();
// Connect to SQL Server database
include("../sqlConnect.php");
// Construct query
$loginName = $_GET['loginName'];
//Ok, let's grab user's dept from query
$sql = "SELECT ISNULL(dept,'NA') AS 'dept' FROM emp where ([userName]) = lower('$userName')"
$stmt = sqlsrv_query( $conn, $sql);
if( $stmt === false )
{
echo "Error in executing query.</br>";
die( print_r( sqlsrv_errors(), true));
}
$results = array();
while($row = sqlsrv_fetch_array($stmt,SQLSRV_FETCH_ASSOC)) {
array_push($results,$row);
$dept = $row['dept'];
}
//Store department in the session
$_SESSION['dept'] = $dept;
//Now extract records based on dept
$tsql ="SELECT
r.REQUESTID,
convert(char(10),r.[currDate],101),
r.[startedDBY],
e.[dept],
e.[WORKPHONE],
e.[EMAIL],
r.[DESCRIPTION],
r.[DETAILS],
r.[PROBLOCATION],
c.[COMMENTS]'
FROM EMPLOYEE e,REQUEST r,CUSTOMERCALL c
WHERE LOGINNAME='$loginName'
AND c.REQUESTID=r.requestid
AND e.dept = '" . $_SESSION['dept'] . "'
";
$stmt = sqlsrv_query( $conn, $tsql);
if( $stmt === false )
{
echo "Error in executing query.</br>";
die( print_r( sqlsrv_errors(), true));
}
$results = array();
while($row = sqlsrv_fetch_array($stmt,SQLSRV_FETCH_ASSOC)) {
array_push($results,$row);
}
echo json_encode($results);
// Free connection resources
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
Converting my code from mysql to SQL server (SQLsrv), but having issue founding the equlent to mysql_field_name as used here:
foreach($this->aCols as $i=>$col)
{
if($col['c']=='')
{
if(is_string($col['f']))
$this->aCols[$i]['c']=ucfirst($col['f']);
else
$this->aCols[$i]['c']=ucfirst(mysql_field_name($res,$col['f']));
}
}
I think it would be sqlsrv_get_field(). See below MSDN document (link) for documentation and code samples:
sqlsrv_get_field
Syntax:
sqlsrv_get_field( resource $stmt, int $fieldIndex)
Taken from MSDN (A sample usage):
$tsql = "SELECT ReviewerName, Comments
FROM Production.ProductReview
WHERE ProductReviewID=1";
$stmt = sqlsrv_query( $conn, $tsql);
if( $stmt === false )
{
echo "Error in statement preparation/execution.\n";
die( print_r( sqlsrv_errors(), true));
}
/* Make the first row of the result set available for reading. */
if( sqlsrv_fetch( $stmt ) === false )
{
echo "Error in retrieving row.\n";
die( print_r( sqlsrv_errors(), true));
}
$name = sqlsrv_get_field( $stmt, 0);
echo "$name: ";
I'm having a really annoying problem with a simple query.
So:
INSERT INTO [SapuV2].[dbo].[ALERGIA] ([DESCRIPCION]) OUTPUT INSERTED.PK_ALERGIA VALUES ('test')
PK_ALERGIA is a primary identity key, and i need the new id created.
PHP code:
$sql = "INSERT INTO ALERGIA (DESCRIPCION) OUTPUT INSERTED.PK_ALERGIA VALUES(?)";
$id = 0;
$params = array(
array(&$nombre, SQLSRV_PARAM_IN),
array(&$id, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_INT)
);
$stmt = sqlsrv_prepare($this->Conn, $sql, $params);
if( sqlsrv_execute($stmt) === false){
die( print_r( sqlsrv_errors(), true) );
}else{
var_dump($id);
}
I'm able to save records on my BD, but $id is always 0 ...
Thanks ;)
Please try this:
INSERT INTO ALERGIA (DESCRIPCION)select #var=scope_identity()
I finally did it, but i'm not proud ...
Using same SQL Query, but change the sqlsrv_execute to a sqlsrv_fetch_array
$sql = "INSERT INTO ALERGIA ([DESCRIPCION]) OUTPUT INSERTED.PK_ALERGIA VALUES (?)";
$params = array(
array(&$nombre, SQLSRV_PARAM_IN)
);
$rows = sqlsrv_query($this->Conn, $sql, $params);
if($rows === false){
die(var_dump(sqlsrv_errors()));
}else{
while($row = sqlsrv_fetch_array($rows, SQLSRV_FETCH_ASSOC)){
var_dump($row);
}
}