> ## Content Index
> Fetch the complete content index at: https://blogs.remobjects.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Using Remote Commands with Data Abstract for Xcode
- URL: https://blogs.remobjects.com/2012/06/05/using-remote-commands-with-data-abstract-for-xcode/
- Published: 2012-06-05T18:14:33.000Z
- Updated: 2018-08-22T06:17:42.000Z
- Author: alexk
- Tags: #Import 2026-08-17 20:17

Recently, we have added some new functionality to the [*DARemoteDataAdapter*](http://wiki.remobjects.com/wiki/DARemoteDataAdapter%5FClass?ref=blogs.remobjects.com) for working with *Data Abstract Commands*.

Let me briefly refresh your memory about what *Commands* are and when they can be helpful.

*Data Abstract Commands* are part of the *DASchema* and represent a reference to certain *Database Stored Procedures* or just keep custom SQL expressions we need to execute.

The most common commands perform INSERT/UPDATE/DELETE actions for given tables.  
In addition, they can be used to perform calculations in the database and return the results to the user.

Before now, we could only perform command calls by using the DataAbstractService\_Proxy directly.  
I’ve posted the workaround for that some days ago [Support for RemoteCommands in DA/Xcode?](http://connect.remobjects.com/discussion/comment/1455?ref=blogs.remobjects.com).

But with the next release it will be much simpler.

To execute commands from the sample mentioned above, we just have to perform the following code:

| \[remoteDataAdapter executeCommand:@"Insert\_BPWorkers" withParameterValuesAndNames:@"John1", @"FirstName", @"Doe1", @"LastName", @"444-22-33-22", @"Phone", \[NSDate date\], @"BirthDate", @"Manager", @"Position", nil\]; |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

The same can easily be done in an \*asynchronous\* way.

But let me show you how it works on a more complex sample with stored procedures that have output parameters.  
Imagine you have an MSSQL database with the following simple *TestStoredProcedure*:

| CREATEPROCEDURE\[dbo\].\[TestStoredProcedure\] @groupId INT\=0, @name nvarchar(255) OUTPUT, @COUNTINT OUTPUT ASBEGINSET NOCOUNT ON; SELECT TOP 1 @name \= p.Name FROM Products p WHERE p.GroupId \= @groupId; SELECT @COUNT\=COUNT(\*)FROM Products p WHERE p.GroupId \= @groupId; RETURN157; END |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

As you have noticed, this stored procedure returns \*@name\* & \*@count\* as output parameters and some \*“magic number”\* as the result. So let’s use it.

**Note** Don't forget that Data Abstract doesn't work with the database objects directly, but with schema objects (tables, commands etc).

If you need to get back the output parameters, you need to use the [**ExecuteCommandEx**](http://wiki.remobjects.com/wiki/IDataAbstractService%5FProtocol?ref=blogs.remobjects.com) method.

Beside the usual arguments like command name and parameters, it takes another *NSDictionary* as the output argument which will contain the output values.

The code for the asynchronous call will look something like this:

| \-(IBAction)callTheCommandEx:(id)sender {NSString\*COMMAND\_NAME \=@"TestStoredProcedure"; NSDictionary\*params \=\[NSDictionary dictionaryWithObjectsAndKeys:\[NSNumber numberWithInt:10\], @"groupId", nil\]; DAAsyncRequest \*request \=\[dataAdapter beginExecuteCommandEx:@"TestStoredProcedure" withParameters:params start:NO\]; \[request setDelegate:self\]; \[request start\]; } \-(void)asyncRequest:(DAAsyncRequest \*)request didFinishExecutingCommand:(NSString\*)commandName withResult:(int)result andOutputParams:(NSDictionary\*)outParams { NSLog(@"Called ExecuteCommandEx for %@ with result %i", commandName, result); NSLog(@"%@", outParams); } |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

Or the same but using \*blocks\*:

| \-(IBAction)callTheCommandEx:(id)sender {\[dataAdapter beginExecuteCommandEx:@"TestStoredProcedure" withParameters:params withBlock:^(int result, NSDictionary\*outParams){ NSLog(@"Called ExecuteCommandEx for %@ with result %i", @"TestStoredProcedure", result); NSLog(@"%@", outParams); }\]; |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

In both cases we’ve got the following results:

| Called ExecuteCommandEx for TestStoredProcedure with result \-1{"RETURN\_VALUE"\=157; count \=42; name \="APC ProtectNet PNET1GB"; } |
| ------------------------------------------------------------------------------------------------------------------------------------ |