'How to loop execution SQLExecute() in c++ with odbc?

Try to use Prepared stmt to loop execut a procdure in SQLServer

Here is my code

bool fileReader::insert(SQLHSTMT hstmt){
SQLPrepare(hstmt, (SQLCHAR*)"addBlock ?", SQL_NTS);
byte* write = (byte*)malloc(80);
SQLLEN cbValueSize = 80;
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 80, 0, write, 80, &cbValueSize);
for (int i = 0; i < sorted; i++)
{
    memcpy(write, blockStore[index[i]].blockHead, 80);
    SQLExecute(hstmt);
}
return true;}

SQL procdure code:

create proc addBlock
@rawBlock binary(80)
as
begin
declare @hashHex binary(32);
declare @hash char(64);
declare @height int;
declare @version bigint;
declare @versionHex varchar(127);
declare @merkleRoot binary(32);
declare @unixTime bigint;
declare @time smalldatetime;
declare @medianTime bigint;
declare @nonce bigint;
declare @bits varchar(127);
declare @difficulty bigint;
declare @chainwork varchar(127);
declare @nTx bigint;
declare @previousBlockHash binary(32);
declare @nextBlockHash binary(32);
declare @strippedSize bigint;
declare @size bigint;
declare @weight bigint;
--will return SQL_ERROR when insert
insert into rawBlockHead(blockHead)
values (@rawBlock);
select @hashHex=hashbytes('SHA2_256', hashbytes('SHA2_256', @rawBlock))
set @hash=substring(master.sys.fn_varbintohexstr(cast(reverse(@hashHex) as binary(32))), 3, 64);
select @height=max(id)
from rawBlockHead;
select @version=cast(reverse(substring(@rawBlock, 1, 4)) as binary(4));
select @versionHex=reverse(substring(@rawBlock, 1, 4));
select @merkleRoot=substring(@rawBlock, 37, 32);
select @unixTime=cast(reverse(substring(@rawBlock, 69, 4)) as binary(4));
select @time=dateadd(S, @unixTime, '1970-01-01');
select @medianTime=0;
select @nonce=substring(@rawBlock, 77, 4);
select @bits=substring(@rawBlock, 73, 4);
select @difficulty=cast(reverse(substring(@rawBlock, 73, 4))as binary(4));
select @chainwork=(select sum(difficulty) from [block] where (height<@height));
select @nTx=0;
select @previousBlockHash=substring(@rawBlock, 5, 32);
select @nextBlockHash=0x00;
select @strippedSize=0;
select @size=80;
select @weight=80;
insert into [block]([hashHex], [hash], height, [version], versionHex, merkleRoot, unixTime, [time], medianTime, nonce, bits, difficulty, chainwork, nTx, previousBlockHash, nextBlockHash, strippedSize, size, [weight])
values (@hashHex, @hash, @height, @version, @versionHex, @merkleRoot, @unixTime, @time, @medianTime, @nonce, @bits, @difficulty, @chainwork, @nTx, @previousBlockHash, @nextBlockHash, @strippedSize, @size, @weight);
update [block]
set nextBlockHash=@hashHex
where [hashHex]=@previousBlockHash;
end

the addBlock should input a binary data and it's length is 80(byte) if execution in dbms,it should like

addBlock 0x0100000000000000000000000000000000000000000000000000000000000000000000003BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA4B1E5E4A29AB5F49FFFF001D1DAC2B7C

when I run this code, in first time, it works good(when i==0)

but when it run next time , function SQLExecute(hstmt) give me back a SQL_ERROR(-1)(i==1,2....etc),

Is it a right way to use prepared statement? or how to fix it?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source