Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Lab Design

chamar Stored Procedures em PHP

Recommended Posts

Galera eu to num briga de foice com a Locaweb por causa disso então eu gostaria de saber se alguem já conseguiu chamar alguma stored procedure do sql server através do php.

 

Eu até consigo chamar via class Ado mas para consultas, agora para inserção de dados, sem chance.

 

Essa é SP que to usando como teste:

 

/*

procedure criado no sql server

USE [ridgid]

GO

 

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE PROCEDURE [dbo].[insertMailing]

@remoteIp nvarchar(20),

@empresa nvarchar(100),

@nome nvarchar(100),

@ender nvarchar(100),

@compl nvarchar(50),

@bairro nvarchar(50),

@cep nvarchar(10),

@cidade nvarchar(50),

@uf nvarchar(2),

@fone nvarchar(70),

@fax nvarchar(30),

@email nvarchar(100),

@op int output -- 0=insert e 1=update

AS

DECLARE @inclusao datetime

DECLARE @status int

DECLARE @divisao int

 

SET @status=1

SET @divisao=0

if exists(SELECT id FROM mailing WHERE email=@email)

begin

SELECT @op=1

return(1)

end

else

begin

begin transaction

INSERT INTO mailing (empresa,nome,ender,compl,bairro,cep,cidade,uf,fone,fax,email,remoteIp,inclusao,

tatus,divisao)

VALUES(@empresa,@nome,@ender,@compl,@bairro,@cep,@cidade,@uf,@fone,@fax,@email,@

emoteIp,getdate(),@status,@divisao)

end

 

 

if @@error <> 0

begin

rollback transaction

SELECT @op=@@error

return(@@error)

end

else

begin

commit transaction

SELECT @op=0

return(0)

end

*/

 

 

Testando ela atraves do manager do sql server ta funcionando corretamente e retorna 0 para inclusão ok ou 1 para erro.

Agora dentro do php...

 

 

include 'global.php'; // informacoes para conexao às bases de dados mysql e sql server

 

// estes dados virão de um form

$remoteIp = '189.1.1.102';

$empresa = 'EMPRESA';

$nome = 'NOME';

$ender = 'ENDEREÇO';

$compl = 'COMPL';

$bairro = 'BAIRRO';

$cep = '01000-000';

$cidade = 'CIDADE';

$uf = 'UF';

$fone = 'TELEFONE';

$fax = 'FAX';

$email = 'fulano@abcd.com.br';

 

 

require '../adodb/adodb.inc.php';

$db = NewADOConnection('mssql');

$db->debug=true;

$db->Connect($msHost,$msUser,$msPwd,$msDataBase) or die("Erro de conexao");

$retorno=0;

 

// a chamada abaixo falha na preparaçao da chamada

// acesso 2 - ADODB execute procedure

# @RETVAL = insertMailing @myid,@group

$retorno=0;

$stmt = $db->PrepareSP("insertMailing");

$db->InParameter($stmt, $remoteIp, "remoteIp");

$db->InParameter($stmt, $empresa, "empresa");

$db->InParameter($stmt, $nome, "nome");

$db->InParameter($stmt, $ender, "ender");

$db->InParameter($stmt, $compl, "compl");

$db->InParameter($stmt, $cep, "cep");

$db->InParameter($stmt, $bairro, "bairro");

$db->InParameter($stmt, $cidade, "cidade");

$db->InParameter($stmt, $uf, "uf");

$db->InParameter($stmt, $fone, "fone");

$db->InParameter($stmt, $temp, "fax");

$db->InParameter($stmt, $email, "email");

 

# true indicates output parameter

$db->OutParameter($stmt,$retorno,'RETVAL');

$db->Execute($stmt);

echo " Linha 88 retorno=$retorno Erro:" . $db->ErrorMsg();

 

 

 

chamando diretamente pelo freeTds:

 

$proc = mssql_init("insertMailing",$msConn);

$temp="exemplo 4";

// atribui os campos

mssql_bind($proc,"@remoteIp", $remoteIP, SQLVARCHAR);

mssql_bind($proc,"@empresa", $empresa, SQLVARCHAR);

mssql_bind($proc,"@nome", $nome, SQLVARCHAR);

mssql_bind($proc,"@ender", $ender, SQLVARCHAR);

mssql_bind($proc,"@compl", $compl, SQLVARCHAR);

mssql_bind($proc,"@cep", $cep, SQLVARCHAR);

mssql_bind($proc,"@bairro", $bairro, SQLVARCHAR);

mssql_bind($proc,"@cidade", $cidade, SQLVARCHAR);

mssql_bind($proc,"@uf", $uf, SQLVARCHAR);

mssql_bind($proc,"@fone", $fone, SQLVARCHAR);

mssql_bind($proc,"@fax", $temp, SQLVARCHAR);

mssql_bind($proc,"@email", $email, SQLVARCHAR);

mssql_bind($proc,"RETVAL", $retorno, SQLINT2);

 

mssql_execute($proc); // executa chamada

mssql_free_statement($proc); // libera memória

 

Essa tentativa também falha logo na primeira chamada mssql_init()

 

A única forma que consegui gravar os dados foi enganando o Ado da seguite forma:

 

// atribuindo todos os parametros como uma grande string

$params =" '189.1.1.102','EMPRESA','SEU NOME','SEU ENDEREÇO','COMPL.','BAIRRO,'01000-000', 'CIDADE','UF','TELEFONE','FAX','fulano@abcd.com.bt'";

$db->Execute("Execute insertMailing $params,$retorno");

 

// o '0' seria a variavel de retorno só que nao retorna nada mesmo que grave os dados ou seja, eu fico no escuro sem saber o que ocorreu.

 

Eu achei um site na net que explica esse problema mas acho que os caras lá tão com preguiça de ler pra resolver isso e caso alguem esteja com o mesmo problema dá uma conferida:

 

http://www.devarticles.com/c/a/PHP/Executi...m-PHP-on-Linux/

 

Porque é importante a SP neste caso?

A empresa tem 8 sites publicados, alguns na plataforma windows outros linux e todos usarão essa database sql server e criando SP eu economizo muita progração no lado dos sites, como tratamento de dados vindo de forms, relacionamento de tabelas e etc... e portanto, isso ficaria tudo a cargo do sql server e não mais dos sites. O detalhe é que esse problema já vem a mais 15 dias e a locaweb não me apresenta uma solução.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oi Eclesiastes, eu ja consultei tudo que pude inclusive se observar no meu exemplo eu tentei executar diretamente pelo mssql usando o init e bind mas o freeTds parece não reconhecer. Eu acredito que é bug do freeTds como mencionado neste site http://www.devarticles.com/c/a/PHP/Executi...m-PHP-on-Linux/ inclusive já passei o link duas vezes pra locaweb.

Eles tambem fizeram diversos testes em vários servidores lá tambem sem sucesso e me pediram algum site que estivesse usando esse recurso e se possivel um info do php para eles compararem com o deles.

Compartilhar este post


Link para o post
Compartilhar em outros sites

É realmente tá uma pedreira se continuar assim, eu vou ter que migrar alguns sistemas pra .net

 

Alguem tem algum site em php que acessa stored procedures no sql server 2000 ou 2005?

 

Se tiver por favor me mandem um link com um phpinfo(); para que eu possa passar pra locaweb tentar resolver, pois já testei em quase todos os sites que tenho hospedado la e nenhum deles funciona:

 

USE [ridgid]

GO

/****** Object: StoredProcedure [dbo].[sp_GetBooksByPrice] Script Date: 11/27/2007 00:54:54 ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE PROC [dbo].[sp_GetBooksByPrice]

@minPrice money,

@maxPrice money,

@lowestPricedBook varchar(100) OUTPUT,

@highestPricedBook varchar(100) OUTPUT

AS

DECLARE @realminPrice money, @realmaxPrice money, @totalBooks int

SELECT @realminPrice = min(price) FROM titles WHERE price >=@minPrice

SELECT @realmaxPrice = max(price) FROM titles WHERE price <=@maxPrice

SELECT @lowestPricedBook =title FROM titles WHERE price = @realminPrice

SELECT @highestPricedBook =title FROM titles WHERE price = @realmaxPrice

SELECT @totalBooks = COUNT(title) FROM titles WHERE price >= @minPrice AND price <= @maxPrice

RETURN @totalBooks

<?php

$myServer = "hostSQL";

$myUser = "usuario";

$myPass = "senha";

$myDB = "database";

 

$s = mssql_connect($myServer, $myUser, $myPass)

or die("Couldn't connect to SQL Server on $myServer");

 

mssql_select_db($myDB, $s)

or die("Couldn't open database $myDB");

 

$proc = mssql_init("sp_GetBooksByPrice", $s);

 

$minPrice = 2.00;

$maxPrice = 20.00;

$lowestPricedBook = "";

$highestPricedBook = "";

$numBooks = 0;

 

// Bind the parameters

 

mssql_bind($proc, "@minPrice", $minPrice, SQLFLT8) or die("Erro de bind");

mssql_bind($proc, "@maxPrice", $maxPrice, SQLFLT8) or die("Erro de bind");

mssql_bind($proc, "@lowestPricedBook", $lowestPricedBook, SQLVARCHAR, TRUE, FALSE,100) or die("Erro de bind");

mssql_bind($proc, "@highestPricedBook", $highestPricedBook, SQLVARCHAR, TRUE, FALSE,100) or die("Erro de bind");

 

// Bind the return value

 

mssql_bind($proc, "RETVAL", $numBooks, SQLINT2) or die("Erro de bind");

 

mssql_execute($proc) or die("Erro de mssql_execute");

mssql_free_statement ($proc);

mssql_close($s);

 

echo "<h2>There were $numBooks Books returned.</h2>";

echo "The lowest price book was: <b>$lowestPricedBook</b>.<br>";

echo "The highest price book was: <b>$highestPricedBook</b>.";

?>

Todos os testes retornam:

Warning: mssql_execute() [function.mssql-execute]: stored procedure execution failed in /home/htdocs/html/portalridgid/sp_teste.php on line 32

Erro de mssql_execute

Compartilhar este post


Link para o post
Compartilhar em outros sites

Somente para documentar:

 

Alterei algumas coisas na Store Procedure

 

USE [ridgid]

GO

/****** Object: StoredProcedure [dbo].[sp_insertMailing] Script Date: 11/27/2007 22:15:51 ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

ALTER PROCEDURE [dbo].[sp_insertMailing]

@remoteIp nvarchar(20),

@empresa nvarchar(100),

@nome nvarchar(100),

@ender nvarchar(100),

@compl nvarchar(50),

@bairro nvarchar(50),

@cep nvarchar(10),

@cidade nvarchar(50),

@uf nvarchar(2),

@fone nvarchar(50),

@fax nvarchar(30),

@email nvarchar(100),

@op int, -- 0=insert e 1=update

@ret int output, -- 0=insert e 1=update

@msgRet nvarchar(255) output -- mensagem de retorno de erro

 

AS

DECLARE @inclusao datetime

DECLARE @status int

DECLARE @divisao int

DECLARE @strDate nvarchar(10)

 

SET @status=1

SET @divisao=0

if exists(SELECT email FROM mailing WHERE email=@email)

begin

SELECT @strDate=CONVERT(char(10), inclusao, 103) FROM mailing WHERE email=@email

SELECT @msgRet='Este email já faz parte de nosso mailing desde '+@strDate

return(1)

end

else

begin

SELECT @msgRet=''

INSERT INTO mailing (empresa,nome,ender,compl,bairro,cep,cidade,uf,fone,fax,email,remoteIp,inclusao,

tatus,divisao)

VALUES(@empresa,@nome,@ender,@compl,@bairro,@cep,@cidade,@uf,@fone,@fax,@email,@

emoteIp,getdate(),@status,@divisao)

if @@error <> 0

return(@@error)

else

return(0)

end

// a conexao com o sql server já foi criada anteriormente no arquivo global.php

 

if (!checkForm()) die("Seu formulário contém caracteres inválidos!"); // verifica sql injections no form

 

// recupera dados do form

$remoteIp = '189.1.1.102';

$empresa = 'EMPRESA';

$nome = 'NOME';

$ender = 'ENDEREÇO';

$compl = 'COMPL';

$bairro = 'BAIRRO';

$cep = '01000-000';

$cidade = 'CIDADE';

$uf = 'UF';

$fone = 'TELEFONE';

$fax = 'FAX';

$email = 'fulano@abcd.com.br';

 

// ********** acesso 1 - freeTds

// declara somente as variaveis para retorno que vai utilizar no select

 

$sql="

DECLARE @ret int, @msgRet varchar(255)

 

execute @ret=sp_insertMailing

'$remoteIp','$empresa','$nome','$ender','$compl','$bairro','$cep','$cidade','$uf','$fone','$fax','$email',0 ,@ret output,@msgRet output

select @ret as numErr, @msgRet as msgErr";

$query=mssql_query($sql); // executa

 

$result=mssql_fetch_object($query); // atribui para o array

debug($result); // mostra o retorno da SP

Retorno do debuf($result) - veja que o numErr=0 e o msgErr=''

stdClass Object

(

[numErr] => 0

[msgErr] =>

)

 

Agora um f5 na tela que força novo post

veja que voltou corretamente o bloco da SP quando acusou a existencia do email na tabela:

if exists(SELECT email FROM mailing WHERE email=@email)

begin

SELECT @strDate=CONVERT(char(10), inclusao, 103) FROM mailing WHERE email=@email

SELECT @msgRet='Este email já faz parte de nosso mailing desde '+@strDate

return(1)

end

stdClass Object

(

[numErr] => 1

[msgErr] => Este email já faz parte de nosso mailing desde 27/11/2007

)

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.