ASP.NET & SQL Server : Incorrect syntax near '?' - asp.net

I am receiving an error
Incorrect syntax near ?
when trying to use a update query function. The code is from SagePay http://www.sagepay.co.uk/file/12136/download-document/DotNetkit%201.2.6.7%20-%202014-08-14.zip?token=BJFwtM7qNnnm5ZCc_l_dOhq4INB0cQTPCxCd5JOpeh4 and relates to their server InFrame implementation.
As far as I can see the order is being passed correctly, and the list of fields, match the database, just not understanding why I am seeing this error. The code was originally created for MySQL but have had to adapt to SQL Server.
I've tried debugging, but cannot actually see what is being committed to the SQL Server from cmd.ExecuteNonQuery(); any help would be much appreciated, here is the code:
private static readonly List<String> FieldNames = new List<String>
{
VendorTxCodeField, AddressResultField, AddressStatusField, AmountField, AvsCv2Field, BankAuthCodeField, BasketField,
BillingFirstnamesField, BillingSurnameField, BillingPhoneField, BillingAddress1Field, BillingAddress2Field, BillingCityField,
BillingPostCodeField, BillingStateField, BillingCountryField, DeclineCodeField, DeliveryFirstnamesField, DeliverySurnameField, DeliveryPhoneField,
DeliveryAddress1Field, DeliveryAddress2Field, DeliveryCityField, DeliveryPostCodeField, DeliveryStateField, DeliveryCountryField,
CapturedAmountField, CardTypeField, CavvField, CurrencyField, CustomerEmailField, Cv2ResultField, ExpiryDateField, FraudResponseField,
GiftAidField, Last4DigitsField, LastUpdatedField, PayerIdField, PayerStatusField, PostCodeResultField,
RelatedVendorTxCodeField, SecurityKeyField, StatusField, StatusMessageField, SurchargeField, ThreeDSecureStatusField,
TransactionTypeField, TxAuthNoField, TokenIdField, VpsTxIdField
};
public static bool UpdateOrder(Order order, string vendorTxCode)
{
var result = false;
SqlConnection conn = null;
try
{
conn = new SqlConnection(ConnectionString);
conn.Open();
var cmd = new SqlCommand
{
Connection = conn, CommandText = "UPDATE Orders SET " + string.Join(",", FieldNames.Select(field => field + "=?" + field).ToList()) + " WHERE " + VendorTxCodeField + " =?" + VendorTxCodeField
};
cmd.Prepare();
AddOrderParameters(cmd, order);
cmd.ExecuteNonQuery();
result = true;
}
catch (SqlException ex)
{
Console.WriteLine("Error: {0}", ex);
}
finally
{
if (conn != null)
{
conn.Close();
}
}
return result;
}
private static void AddOrderParameters(SqlCommand command, Order order)
{
command.Parameters.AddWithValue(VendorTxCodeField, order.VendorTxCode);
command.Parameters.AddWithValue(AddressResultField, order.AddressResult);
command.Parameters.AddWithValue(AddressStatusField, order.AddressStatus);
command.Parameters.AddWithValue(AmountField, order.Amount);
command.Parameters.AddWithValue(AvsCv2Field, order.AvsCv2);
command.Parameters.AddWithValue(BankAuthCodeField, order.BankAuthCode);
command.Parameters.AddWithValue(BasketField, order.Basket);
command.Parameters.AddWithValue(BillingAddress1Field, order.BillingAddress1);
command.Parameters.AddWithValue(BillingAddress2Field, order.BillingAddress2);
command.Parameters.AddWithValue(BillingCityField, order.BillingCity);
command.Parameters.AddWithValue(BillingCountryField, order.BillingCountry);
command.Parameters.AddWithValue(BillingFirstnamesField, order.BillingFirstnames);
command.Parameters.AddWithValue(BillingPhoneField, order.BillingPhone);
command.Parameters.AddWithValue(BillingPostCodeField, order.BillingPostCode);
command.Parameters.AddWithValue(BillingStateField, order.BillingState);
command.Parameters.AddWithValue(BillingSurnameField, order.BillingSurname);
command.Parameters.AddWithValue(CapturedAmountField, order.CapturedAmount);
command.Parameters.AddWithValue(CardTypeField, order.CardType);
command.Parameters.AddWithValue(CavvField, order.Cavv);
command.Parameters.AddWithValue(CurrencyField, order.Currency);
command.Parameters.AddWithValue(CustomerEmailField, order.CustomerEmail);
command.Parameters.AddWithValue(Cv2ResultField, order.Cv2Result);
command.Parameters.AddWithValue(DeclineCodeField, order.DeclineCode);
command.Parameters.AddWithValue(DeliveryAddress1Field, order.DeliveryAddress1);
command.Parameters.AddWithValue(DeliveryAddress2Field, order.DeliveryAddress2);
command.Parameters.AddWithValue(DeliveryCityField, order.DeliveryCity);
command.Parameters.AddWithValue(DeliveryCountryField, order.DeliveryCountry);
command.Parameters.AddWithValue(DeliveryFirstnamesField, order.DeliveryFirstnames);
command.Parameters.AddWithValue(DeliveryPhoneField, order.DeliveryPhone);
command.Parameters.AddWithValue(DeliveryPostCodeField, order.DeliveryPostCode);
command.Parameters.AddWithValue(DeliveryStateField, order.DeliveryState);
command.Parameters.AddWithValue(DeliverySurnameField, order.DeliverySurname);
command.Parameters.AddWithValue(ExpiryDateField, order.ExpiryDate);
command.Parameters.AddWithValue(FraudResponseField, order.FraudResponse);
command.Parameters.AddWithValue(GiftAidField, order.GiftAid);
command.Parameters.AddWithValue(Last4DigitsField, order.Last4Digits);
command.Parameters.AddWithValue(LastUpdatedField, order.LastUpdated);
command.Parameters.AddWithValue(PayerIdField, order.PayerId);
command.Parameters.AddWithValue(PayerStatusField, order.PayerStatus);
command.Parameters.AddWithValue(PostCodeResultField, order.PostCodeResult);
command.Parameters.AddWithValue(RelatedVendorTxCodeField, order.RelatedVendorTxCode);
command.Parameters.AddWithValue(SecurityKeyField, order.SecurityKey);
command.Parameters.AddWithValue(StatusField, order.Status);
command.Parameters.AddWithValue(StatusMessageField, order.StatusMessage);
command.Parameters.AddWithValue(SurchargeField, order.Surcharge);
command.Parameters.AddWithValue(ThreeDSecureStatusField, order.ThreeDSecureStatus);
command.Parameters.AddWithValue(TokenIdField, order.TokenId);
command.Parameters.AddWithValue(TransactionTypeField, order.TransactionType);
command.Parameters.AddWithValue(TxAuthNoField, order.TxAuthNo);
command.Parameters.AddWithValue(VpsTxIdField, order.VpsTxId);
}

You have to use # for sql-parameters. Maybe this fixes your issue although i must admit that i don't understand the query because the column-names are the same as the values. However ...
string sql = #"UPDATE Orders SET {0}
Where {1}=#{1};";
sql = string.Format(sql
, string.Join(",", FieldNames.Select(field => string.Format("{0}=#{0}", field)))
, VendorTxCodeField);
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
for (int i = 0; i < FieldNames.Count; i++)
{
cmd.Parameters.AddWithValue(FieldNames[i], FieldNames[i]);
}
// open connection and execute the command...
}

Related

How to perform a parallel CMIS requests in Alfresco?

I have several CMIS requests and need to do them in parallel. But when I try it (using CompletableFutire or stream().parallel(), I got:
java.util.concurrent.ExecutionException: net.sf.acegisecurity.AuthenticationCredentialsNotFoundException: A valid SecureContext was not provided in the RequestContext
For that queries I do :
#Autowired
#Qualifier("searchService")
private org.alfresco.service.cmr.search.SearchService searchService;
....
searchService.query(searchParameters);
What am I doing wrong?
The following code is one of my attempt to perform CMIS in parallel:
List<CompletableFuture<Form14Row>> requests = Arrays.asList(setUpRow(1,beginnigString, endString, docType, NDBaseDocumentModel.DOC_KIND_GOST_R, searchParameters, "ГОСТ Р"),
setUpRow(2,beginnigString, endString, docType, NDBaseDocumentModel.DOC_KIND_GOST, searchParameters, "ГОСТ") );
CompletableFuture<Void> allRequests = CompletableFuture.allOf(
requests.toArray(new CompletableFuture[requests.size()])
);
CompletableFuture<List<Form14Row>> allPageContentsFuture = allRequests.thenApply(v -> {
return requests.stream()
.map(pageContentFuture -> pageContentFuture.join())
.collect(Collectors.toList());
});
//java.util.concurrent.ExecutionException: net.sf.acegisecurity.AuthenticationCredentialsNotFoundException: A valid SecureContext was not provided in the RequestContext
try {
List<Form14Row> rowss = allPageContentsFuture.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
...
private CompletableFuture<Form14Row> setUpRow(Integer index, String beginnigString, String endString, String docType, String docKind, SearchParameters searchParameters, String groupPosition) {
return CompletableFuture.supplyAsync(() -> {
String cql = "SELECT p.cmis:objectId FROM ecmcnddoc:common_attr_aspect AS d JOIN ecmcnddoc:biblio_attr_aspect AS p ON d.cmis:objectId = p.cmis:objectId JOIN ecmcnddoc:reg_attr_aspect AS s ON s.cmis:objectId = p.cmis:objectId JOIN ecmcnddoc:spec_attr_aspect AS asp ON asp.cmis:objectId = p.cmis:objectId WHERE p.cmis:objectTypeId='D:" + docType + "' AND d.ecmcnddoc:doc_kind_cp_ecmcdict_value='" + docKind + "' AND p.ecmcnddoc:biblio_fond='" + NDBaseDocumentModel.BIBLIO_FUND + "' AND s.ecmcnddoc:doc_reg_date >= TIMESTAMP '" + beginnigString + "T00:00:00.000+00:00' AND s.ecmcnddoc:doc_reg_date <= TIMESTAMP '" + endString + "T00:00:00.000+00:00' AND (asp.ecmcnddoc:doc_status='draft' OR asp.ecmcnddoc:doc_status='actual')";
searchParameters.setQuery(cql);
ResultSet rs = customSearchService.query(searchParameters); // Exception here
Form14Row isoRow = new Form14Row();
isoRow.setCount(rs.length());
isoRow.setIndex(index);
isoRow.setKindName(groupPosition);
return isoRow;
});
}
Everything works fine in serial execution
Security context is binded to main thread and is not propagated to children threads, you would need to set one.
Maybe you could try to adapt this snippet:
CompletableFuture.runAsync(() -> {
try {
AuthenticationUtil.pushAuthentication();
AuthenticationUtil.setFullyAuthenticatedUser(userName);
// Do your stuff...
} finally {
AuthenticationUtil.popAuthentication();
}
});

How to move Resultset curser via button click, and display data in textfields?

So, I'm creating a desktop banking application. It's nothing too serious, I'm just trying to practice and get better.
// Method I use to get a connection. I know this works.
public static Connection getConnection() throws SQLException {
String sCon = "jdbc:sqlite:banking.sqlite";
Connection connection = DriverManager.getConnection(sCon);
return connection;
}
.
..
...
.....Other code
Method I attempt to use to create and manipulate the data in the result set.
The problem I believe starts here. With this code, I am only able to return one row of the result set and only the last row.
public static Customers getAccounts(Customers c) {
String query = "select RowCount, Customers.Account_Number, "
+ "Customers.First_Name, Last_Name, Address, "
+ "Phone_Number, Accounts.Balance "
+ "from Customers "
+ "join Accounts ";
try (Connection connection = getConnection();
PreparedStatement ps = connection.prepareStatement(query);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
String fName = rs.getString("First_Name");
String lName = rs.getString("Last_Name");
String address = rs.getString("Address");
String phone = rs.getString("Phone_Number");
String accNum = rs.getString("Account_Number");
String balance = rs.getString("Balance");
c.setFirstName(fName);
c.setLastName(lName);
c.setAddress(address);
c.setPhoneNumber(phone);
c.setAccountNumber(accNum);
c.setBalance(balance);
}
return c;
} catch (SQLException e) {
System.err.println(e);
}
return null;
}
}
Here is the method that is linked to the button I use to perform what I'm trying to attempt. It's part of the Controller class. I believe this method is also a part of the problem. Any ideas? Thank for all you guys do. This website is a real benefit to the community.
public void next() {
Customers c = new Customers();
DBInterface.getAccounts(c);
firstNameF2.setText(c.getFirstName());
lastNameF2.setText(c.getLastName());
addressF2.setText(c.getAddress());
phoneNumberF2.setText(c.getPhoneNumber());
accNumF.setText(c.getAccountNumber());
balanceF.setText(c.getBalance());
}
If you are expecting to get multiple Customers objects, then you definitely should return a list of that.
public static List<Customers> getAccounts() {
// Whatever you originally had...
final List<Customers> ret = new ArrayList<>();
while (rs.next()) {
String fName = rs.getString("First_Name");
String lName = rs.getString("Last_Name");
String address = rs.getString("Address");
String phone = rs.getString("Phone_Number");
String accNum = rs.getString("Account_Number");
String balance = rs.getString("Balance");
final Customers cust = new Customers();
cust.setFirstName(fName);
cust.setLastName(lName);
cust.setAddress(address);
cust.setPhoneNumber(phone);
cust.setAccountNumber(accNum);
cust.setBalance(balance);
ret.add(cust);
}
return ret;
}
I have removed the part about passing in the instance of Customers (which would have ended up as passing in List<Customers>. If you really need to do that, you can add back in and do all the necessary checks.

Asynchronous , Async Await

I have list of sensor details and i need to get configuration setting for each sensor and apply some business logic. I want to do Aynchrosnously, like each sensor will call the same method and execute its logic at the same time.I tried with Async and await and below is sample. Please let me know, if the below will help to execute each sensor execute asynchronously.
public static async Task GetSensor()
{
List<SensorMaster> sensorAddress = GetSensorService();
foreach (SensorMaster sensorInfo in sensorAddress)
{
await ParseSensor(sensorInfo);
}
}
private static async Task ParseSensor(SensorMaster senInfo)
{
List<Sensor> sTestdownTime = await GetTestDownTime(senInfo);
if (DateTime.Parse(sTestdownTime[0].LastHeartBeatAt.ToString()).Year > 1900)
{
CreateEvent(senInfo, sTestdownTime);
}
}
public static async Task<List<Sensor>> GetTestDownTime(SensorMaster senInfo)
{
List<Sensor> lstSensor = new List<Sensor>();
var connectionString = "Data Source=xxxx;Initial Catalog=xx;persist security info=True;User ID=xx;Password=xxx;";
var asyncConnectionString = new SqlConnectionStringBuilder(connectionString) { AsynchronousProcessing = true }.ToString();
using (var cn = new SqlConnection(asyncConnectionString))
{
cn.Open();
SqlCommand cmd = new SqlCommand("SetingSp", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#StationType", senInfo.SensorName));
cmd.Parameters.Add(new SqlParameter("#ThresholdValue", senInfo.SensorThreshold));
using (SqlDataReader dr = await cmd.ExecuteReaderAsync())
{
if (dr.HasRows)
{
while (dr.Read())
{
Sensor cpData = new Sensor();
cpData.SensorName = dr["SensorName"].ToString();
cpData.LastHeartBeatAt = Convert.ToDateTime(dr["LastTimeStamp"]);
lstSensor.Add(cpData);
}
}
}
return lstSensor;
}
}
Yes, they will execute asynchronously. But not in parallel. And I don't think you should even try to make it parallel unless you have a very clear performance problem.
Going parallel (with for example Parallel.ForEach()) would open many SqlConnections at once. Unclear on what kind of system you are running, and what would be expected.

How to get out integer from database using IDataReader and Mapper

I'm very new in programming and this is my first post (question) here, so please don't judge me.
I'm trying to build my first individual WCF service for my project. Let me first display my code , so it will be easier to understand.
This is my data access layer:
public class DataAccessLayer : IDisposable
{
string DBConnectionString = "DBCS";
public int ValidateUser(string employeeLogin, string employeePassword)
{
int outputResult = 0;
try
{
DatabaseProviderFactory factory = new DatabaseProviderFactory();
Database db = factory.Create(DBConnectionString);
string storedProcedureName = "uspValidateUser";
DbCommand dbCommand = db.GetStoredProcCommand(storedProcedureName);
db.AddInParameter(dbCommand, "#EmployeeLogin", DbType.String, employeeLogin);
db.AddInParameter(dbCommand, "#EmployeePassword", DbType.String, employeePassword);
db.AddOutParameter(dbCommand, "#OutRes", DbType.Int32, outputResult);
using (IDataReader reader = db.ExecuteReader(dbCommand))
{
Mapper.Reset();
Mapper.CreateMap<IDataReader, Int32>();
outputResult = (int)Mapper.Map<IDataReader, Int32>(reader);
}
}
catch (Exception ex)
{
throw ex;
}
return outputResult;
}
public void Dispose()
{
}
}
This is my stored procedure:
ALTER PROCEDURE [dbo].[uspValidateUser]
#EmployeeLogin VARCHAR(20),
#EmployeePassword VARCHAR(20),
#OutRes int Output
AS
SET #OutRes = (select count(*)
from dbo.tblEmployee
where EmployeeLogin = #EmployeeLogin
and EmployeePassword = #EmployeePassword)
if (#OutRes = 1)
BEGIN
SET NOCOUNT ON;
set #OutRes = 1 --Login is correct
end
else
BEGIN
set #OutRes = 0 -- Login is incorrect
END
And code behind my web form:
public int ValidateUser(string employeeLogin, string employeePassword)
{
int outputResults = 0;
try
{
using (HospitalWCFService.ContractsClient objWCFService = new HospitalWCFService.ContractsClient())
{
outputResults = objWCFService.ValidateUser(employeeLogin, employeePassword);
}
}
catch (Exception ex)
{
lgnEmployeeLogin.FailureText = ex.Message;
}
return outputResults;
}
protected void ValidateUser(object sender, AuthenticateEventArgs e)
{
int outputResults = 0;
outputResults = ValidateUser(lgnEmployeeLogin.UserName, lgnEmployeeLogin.Password);
if (outputResults == 1)
{
Session["UserName"] = lgnEmployeeLogin.UserName.ToString();
FormsAuthentication.RedirectFromLoginPage(lgnEmployeeLogin.UserName, lgnEmployeeLogin.RememberMeSet);
}
else
{
lgnEmployeeLogin.FailureText = "Username and/or password is incorrect.";
}
}
To get user credentials I'm using login control lgnEmployeeLogin.
I'm having problems of retrieving that output integer #OutRes parameter from database using Mapper (I need to use mapper)
If it is possible, please explain solution in easiest language possible as I might not understand difficult technical slang.
Thank you all in advance!
Your lack of answers could be because you say that you have to use mapper - but I chose to ignore that, because ExecuteReader is for dealing with the rows and columns returned by a stored procedure, not for its output parameters. The stored procedure you provided has no result set!
This could be as simple as
db.ExecuteNonQuery();
OutputResult = db.Parameters( "#OutRes").value
to be clear, this replaces your using...ExecuteReader block
Also note: your code did not deal with opening (and closing) the SQL connection (db.Connection.Open();, so I ignored that here too.

Remove role and recovery the role in the table

for a mistake. I used a wrong command. I wanted to remove an user' role from the table aspnet_UsersInRoles.
I guess that the command might be
Roles.RemoveUserFromRole(userName, origin_role);
However I used a wrong command mistakenly.
Roles.DeleteRole(origin_role,false);
Originally the table has 4 roles. Now the RoleId in the table only has two,
61572264-4935-461d-9d8c-71f147f28c34
c09f25e6-fd6a-447b-8e0d-eba0cfc94e40
How can I find and recovery them?
Many many thanks.
Hate to say it, but you're hosed. The default ASP.Net providers don't include any sort of auditing or soft-delete. If you have a database backup, you can explore/restore from that.
Below you find the source code for the function you called.
It calls the dbo.aspnet_Roles_DeleteRole stored procedure.
I don't have access to an asp.net membership database at the moment, otherwise I would check for you.
You might want to check what the stored procedure does, but as ssyladin mentioned I doubt you will be able to recover anything (since you sent the throwOnPopulatedRole argument to false).
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
SecUtility.CheckParameter(ref roleName, true, true, true, 256, "roleName");
try {
SqlConnectionHolder holder = null;
try {
holder = SqlConnectionHelper.GetConnection(_sqlConnectionString, true);
CheckSchemaVersion( holder.Connection );
SqlCommand cmd = new SqlCommand("dbo.aspnet_Roles_DeleteRole", holder.Connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = CommandTimeout;
SqlParameter p = new SqlParameter("#ReturnValue", SqlDbType.Int);
p.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(p);
cmd.Parameters.Add(CreateInputParam("#ApplicationName", SqlDbType.NVarChar, ApplicationName));
cmd.Parameters.Add(CreateInputParam("#RoleName", SqlDbType.NVarChar, roleName));
cmd.Parameters.Add(CreateInputParam("#DeleteOnlyIfRoleIsEmpty", SqlDbType.Bit, throwOnPopulatedRole ? 1 : 0));
cmd.ExecuteNonQuery();
int returnValue = GetReturnValue(cmd);
if( returnValue == 2 )
{
throw new ProviderException(SR.GetString(SR.Role_is_not_empty));
}
return ( returnValue == 0 );
}
finally
{
if( holder != null )
{
holder.Close();
holder = null;
}
}
}
catch
{
throw;
}
}

Resources