Datasnap Delphi XE5 Server side dynamic sql - sql-server

I am having a small problem with datasnap in delphi Xe5.
I need to run dynamic queries on the server side. I am using an ADO connection on the server methods.
Server Procedure:
var
qryNew: TADOQuery;
dspNew: TDatasetProvider;
begin
qryNew := TADOQuery.Create(nil);
qryNew.Connection := Adoconnection1;
qryNew.SQL.Text := SQL;
qryNew.Name := 'qry'+IntToStr(1);
dspNew := TDatasetProvider.Create(nil);
dspNew.Name := 'dsp'+IntToStr(1);
dspNew.Dataset := qryNew;
qryNew.Open;
Result := dspNew.Name;
end;
Client side procedure:
ClientDataset1.ProviderName :=clientmodule3.ServerMethods1Client.GetDataForClient('Select top 10 * from ODBC.trans_day_2009_1111;');
On the main form i have a SQLconnection, DSProvider connection and a client dataset. When I try to set the provider name for the client with the above code, i get the error "Remote error: Provider not exported : DSP1"

Usually (not always), error messages are helpful if you spend the time to understand them. If it says the provider is not exported, you should have checked why it wasn't - i.e. the doc says:
"To enable the remote data module to pass calls to the provider, the provider's Exported property must be True, and its Owner property must specify the remote data module."
http://docwiki.embarcadero.com/Libraries/XE5/en/Datasnap.Provider.TDataSetProvider
Your provider has no owner.

Related

Using SQL Server connection string with firedac

Using Delphi 10.2, I am trying to use a standard SQL Server connection string with Firedac, but can't seem to make it work.
This is my connection string:
Data Source=PSI-PC006\MSSQL2008;Initial Catalog=PlayGround;Integrated Security=True;Pooling=False;
My code is simply:
function tdmMain.doConnect(const connection : string) : boolean;
begin
dmConnect.cnxData.ConnectionString := connection;
dmConnect.cnxData.DriverName := 'MSSQL';
try
dmConnect.cnxData.Connected := true;
result := true;
except
on E:Exception do
begin
ShowMessage('Connection error' + e.Message);
result := false;
end;
end;
end;
I am trying to make it so that I don't have to load from an ini file, that my application can just be called with the connection string.
Is this even possible?
You don't need to do what you are trying, in order to set up the connection string.
Just double-click your FDConnection1 in the IDE form editor then, in the "FireDAC Connection Editor" pop-up, on the Definition tab, just fill in the parameters you need to specify to make the connection.
Using the FireDAC Connection Editor sets the Params property of your FDConnection. If you want to adjust the FD equivalent of the MSSS Connection String at runtime, you can do direct assignments to the parameter values as per usual.
The FireDac connection string is not same as a SQL Server connection string. It also includes the driver name so you do not need to do that separately.
Server=PSI-PC006\MSSQL2008;OSAuthent=Yes;Database=PlayGround;DriverID=MSSQL
If you use the connection configuration dialog box in the Delphi UI you can see the name=value pairs by clicking on the .. to the right of the Parameters property. The connection string is just those name=:value pairs separated by semicolons.

R: No applicable method for 'tbl' error when making a SQL Server query using dplyr and pool

Apologies if this has been answered elsewhere, but I could not find it. With the following code I am connecting to an MS SQL database using the RJDBC mechanism using pooling from the pool package:
library(RJDBC)
library(DBI)
library(pool)
library(dplyr)
drv <-
JDBC(
"com.microsoft.sqlserver.jdbc.SQLServerDriver",
"C:/R/RJDBC/Microsoft JDBC Driver 6.0 for SQL Server/sqljdbc_6.0/enu/jre8/sqljdbc42.jar"
)
pool_instance <- dbPool(
drv = drv,
dbname = "dbasename",
url = "jdbc:sqlserver://sql01",
user = "user",
password = "password"
)
mydata <- dbGetQuery(pool_instance, "select * from my.Table")
src_pool(pool_instance) %>% tbl("my.Table") %>% head(5)
When I run this code, I make a successful connection to my SQL Server database and the dbGetQuery function call retrieves the data as expected.
However, when I call the src_pool function I get the following error message:
Error in UseMethod("tbl") : no applicable method for 'tbl' applied
to an object of class "c('src_', 'src_sql', 'src')"
If I call the function src_pool(pool_instance) separately, without piping to the tbl function, the error message is similar:
Error in UseMethod("src_desc") : no applicable method for
'src_desc' applied to an object of class "c('src_', 'src_sql', 'src')"
I expected that either dplyr or pool would provide for these methods? Do I need to write code for these methods? What am I missing?
Note that I am a newby to SQL Server database connectivity.

Bug with multiple TADOConnections

I already figured out a display table bug using ADO and SQL Server and different connections to one database. ( see details at BUG #1 )
Another issues come while trying to delete records
The code goes like this
function resettable (tablename, databasename, servername) : Boolean;
var
aADOQuery : TADOQuery;
aADOConnection : TAdoConnection,
begin
/// Create ADO stuff
aADOQuery := TADOQuery.Create;
aADOConnection := TAdoConnection.Create;
/// connect to DB & Table
....
///
aADOQuery.sql.add('delete * from ' + Tablename;
aADOQuery.execsql;
/// free objects after use
....
end;
This code works fine when the ADOConnection is alone on the database. If there has been some activity by any other ADO connection and some modification done, the code fails while the "database is not updated error message"
How to create a solution which will do an update prior to the delete record statement ???

How to make ADO parameter to update SQL Server datetime column?

edit I should have mentioned that I'm trying to do this with Delphi 2006.
OK, I think I have hit on a question with no previous answers.
I have a SQL Server database with columns of type datetime. When I try to insert a row with a parametrized command, I get
Exception class EOleException with message
'[Microsoft][ODBC SQL Server Driver]Optional feature not implemented'.
My insert procedure looks like this:
procedure TForm1.btnZoomClick(Sender: TObject);
const
InsCmd = 'insert into dbo.foo (added, edited, editor, narrative) ' +
'values (:dateAdded, :dateEdited, :theEditor, :theNarrative);';
begin
dmDbToy2.DataModule2.ADOCommand1.CommandText := InsCmd;
with DataModule2.ADOCommand1.Parameters do
begin
// the following line was an attempt to trick VarAsType into making a
// adDbTimeStamp: VarAsType is having none of it.
// FindParam('dateAdded').Value := VarAsType(VarFromDateTime(Now), 135);
FindParam('dateAdded').Value := VarFromDateTime(Now);
FindParam('dateEdited').Value := Null;
FindParam('theEditor').Value := 'wades';
FindParam('theNarrative').Value := Null;
end;
DataModule2.ADOCommand1.Execute;
end;
I found some postings via google which seem to indicate that SQL Server wants a adDbTimeStamp type to update these columns, but VarAsType does not want to make one for me.
Is there a way to create a value for the dateAdded and dateEdited parameters in the code sample?
In the comments thread on the original question, user RRUZ made a suggestion that turned out to resolve the issue: The problem was with the provider. Namely, I was using the OLEDB Provider for ODBC rather than the OLEDB Provider for SQL Server. Changing the provider as suggested made the 'Optional feature not implemented' error message go away and enabled the insert to work with a simple assignment of TDateTime to TParameter.Value, thusly:
FindParam('dateAdded').Value := Now;
Set the datatype for the parameter, it might do a difference in how the parameters is treated. I would also recommend that you use ParamByName instead of FindParam. With ParamByName you get a Param xx not found exception if the parameters does not exist in the Parameters collection. FindParam returns nil if it is not found. I have never needed to use any variant conversion stuff when assigning parameters for a TADOCommand so think you should remove that as well.
Try this.
with ParamByName('dateAdded') do
begin
DataType := ftDateTime;
Value := Now;
end;
with ParamByName('dateEdited') do
begin
DataType := ftDateTime;
Value := Null;
end;
with ParamByName('theEditor') do
begin
DataType := ftString; // or ftWideString if you use nchar/nvarchar
Value := 'wades';
end;
with ParamByName('theNarrative') do
begin
//DataType := ftString // Don't know datatype here
Value := Null;
end;
Just set the parameter as a datetime. I do it all the time in ADO and other conection layers
DataModule2.ADOCommand1.Parameters.ParamByName('dateAdded').Value := Now();
//other code
DataModule2.ADOCommand1.Parameters.ParamByName('dateEdited').Value := Null;
//other code
DataModule2.AdoCommand1.Execute;

Delphi 5.0 Open Interbase/FireBird connection via code

This is old stuff! Is related to delphi 5.0 and interbase 1.6.
I'm trying to open a DB connection via code. But this code is related to enabling the connection, all the components were added using delphi drag-drop User Interface: DataSource1, TForm1, DBGrid, DBNavigator etc..
procedure TDataModule2.DataModuleCreate(Sender: TObject);
begin
database.DatabaseName:='C:\MyDatabase.GDB';
database.Connected := true;
database.Open;
IBTransaction.Active := true;
myTable.Open;
end;
I have a TForm with DBGrid and DBNavigator component. I also have a TIBQuery (that DataSource1 is associated to) with this code on the SQLStrings:
SELECT * FROM NEW_TABLE
On the Form I have this code to enable DBNavigator and DBGrid to show the DB Values. The DB is very simple is just a table: NEW_TABLE with a NEW_VALUE of VARCHAR type
procedure TForm1.FormCreate(Sender: TObject);
begin
DataSource1.DataSet.Open;
// This will call the query associated to this DataSource1 the tibQuery1 to call
// SELECT * FROM NEW_TABLE, but the message below appears: IBClientError...
end;
The message appears:
IBClientError with message 'Database not assigned'
OBS1: If I connect the components by hand on delphi user interface, the connection with the DB is established.
You have to assign the Database property of your query, something like:
IBQuery1.Database := MyDatabase;

Resources