Insert and Update BULK XML data into SQL

Problem
In my last article, I talked about how you can use an  FTP task in SSIS to download files from an FTP server. But what if the file you have downloaded is an XML file and you need to import this data from the XML file into a SQL Server table? How do you process/parse XML data into SQL Server tables?
Solution
There are different ways to achieve this task of importing data from an XML file into a SQL Server table, but I am going to demonstrate one of easiest ways to accomplish this task.
These are the steps I performed for importing data into SQL Server and then parsing the XML into a relational format.
  • Import XML data from an XML file into SQL Server table using the OPENROWSET function
  • Parse the XML data using the OPENXML function

Importing XML data from XML file using OPENROWSET

I have an XML file downloaded from my FTP location to a local folder and data in this XML file looks like this:
Importing XML data from XML file using OPENROWSET
Now in order to import data from the XML file to a table in SQL Server, I am using the OPENROWSET function as you can see below.
In the script below, I am first creating a table with a column of data type XML and then reading the XML data from the file using the OPENROWSET function by specifying the file location and name of the XML file as you can see below: 
CREATE DATABASE OPENXMLTesting
GO


USE OPENXMLTesting
GO


CREATE TABLE XMLwithOpenXML
(
Id INT IDENTITY PRIMARY KEY,
XMLData XML,
LoadedDateTime DATETIME
)


INSERT INTO XMLwithOpenXML(XMLData, LoadedDateTime)
SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE() 
FROM OPENROWSET(BULK 'D:\OpenXMLTesting.xml', SINGLE_BLOB) AS x;


SELECT * FROM XMLwithOpenXML
When I query the table in which I have imported the XML data, it looks like this. The XMLData column is an XML data type, it will output a hyperlink as shown below:
As XMLData column is of XML data type, it will give an hyperlink
Clicking on the hyperlink, in the above image, will open another tab within SSMS with the XML data displayed as shown below.
<ROOT>
<Customers>
<Customer CustomerID="C001" CustomerName="Arshad Ali">
<Orders>
<Order OrderID="10248" OrderDate="2012-07-04T00:00:00">
<OrderDetail ProductID="10" Quantity="5" />
<OrderDetail ProductID="11" Quantity="12" />
<OrderDetail ProductID="42" Quantity="10" />
</Order>
</Orders>
<Address> Address line 1, 2, 3</Address>
</Customer>
<Customer CustomerID="C002" CustomerName="Paul Henriot">
<Orders>
<Order OrderID="10245" OrderDate="2011-07-04T00:00:00">
<OrderDetail ProductID="11" Quantity="12" />
<OrderDetail ProductID="42" Quantity="10" />
</Order>
</Orders>
<Address> Address line 5, 6, 7</Address>
</Customer>
<Customer CustomerID="C003" CustomerName="Carlos Gonzlez">
<Orders>
<Order OrderID="10283" OrderDate="2012-08-16T00:00:00">
<OrderDetail ProductID="72" Quantity="3" />
</Order>
</Orders>
<Address> Address line 1, 4, 5</Address>
</Customer>
</Customers>
</ROOT>

Process XML data using OPENXML function

Now as I said before, XML data stored in a column of data type XML can be processed either by using XML functions available in SQL Server or by using the sp_xml_preparedocument stored procedure along with the OPENXMLfunction.
We will first call the sp_xml_preparedocument stored procedure by specifying the XML data which will then output the handle of the XML data that it has prepared and stored in internal cache.
Then we will use the handle returned by the sp_xml_preparedocument stored procedure in the OPENXML function to open the XML data and read it.
Note: the sp_xml_preparedocument stored procedure stores the XML data in SQL Server's internal cache, it is essential to release this stored XML data from internal cache by calling the sp_xml_removedocument stored procedure. We should call the sp_xml_removedocument stored procedure as early possible, so that internal cache can be freed for other usage.
USE OPENXMLTesting
GO


DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)


SELECT @XML = XMLData FROM XMLwithOpenXML


EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML


SELECT CustomerID, CustomerName, Address
FROM OPENXML(@hDoc, 'ROOT/Customers/Customer')
WITH 
(
CustomerID [varchar](50) '@CustomerID',
CustomerName [varchar](100) '@CustomerName',
Address [varchar](100) 'Address'
)


EXEC sp_xml_removedocument @hDoc
GO
From the above XML data, I want to retrieve all the customer information and hence I am navigating to the Customer element and querying CustomerID and CustomerName (please note the use of "@" before the name of the attribute) attributes and Address element in the above SELECT statement using the OPENXML function.
The structure of the resultset can be determined with the "WITH" clause as shown above.
Process XML data using OPENXML function
From the above XML data, I now want to retrieve all the customer information along with OrderID and OrderDate placed by each individual customer and hence I am navigating to the Order element and then querying OrderID and OrderDate attributes.
If we want to navigate back to the parent or grand parent level and get data from there, we need to use "../" to read the parent's data and "../../" to read the grand parent's data and so on.
USE OPENXMLTesting
GO


DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)


SELECT @XML = XMLData FROM XMLwithOpenXML


EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML


SELECT CustomerID, CustomerName, Address, OrderID, OrderDate
FROM OPENXML(@hDoc, 'ROOT/Customers/Customer/Orders/Order')
WITH 
(
CustomerID [varchar](50) '../../@CustomerID',
CustomerName [varchar](100) '../../@CustomerName',
Address [varchar](100) '../../Address',
OrderID [varchar](1000) '@OrderID',
OrderDate datetime '@OrderDate'
)


EXEC sp_xml_removedocument @hDoc
GO
The result of the above query can be seen in the image below. You can see below all the customers and all the orders placed by each customer.
querying CustomerID and CustomerName
Now let's go one level deeper. This time from the above XML data, I want to retrieve all the customer information and their orders along with ProductID and Quantity from each order placed. And hence, as you can see below I am navigating to the OrderDetail and retrieving the ProductID and Quantity attributes' values. At the same time I am using "../" to reach the parent level to get Order information available at the parent level whereas I am using "../../../" to reach to the great grand parent level to grab Customer information as shown below:
USE OPENXMLTesting
GO


DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)


SELECT @XML = XMLData FROM XMLwithOpenXML


EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML


SELECT CustomerID, CustomerName, Address, OrderID, OrderDate, ProductID, Quantity
FROM OPENXML(@hDoc, 'ROOT/Customers/Customer/Orders/Order/OrderDetail')
WITH 
(
CustomerID [varchar](50) '../../../@CustomerID',
CustomerName [varchar](100) '../../../@CustomerName',
Address [varchar](100) '../../../Address',
OrderID [varchar](1000) '../@OrderID',
OrderDate datetime '../@OrderDate',
ProductID [varchar](50) '@ProductID',
Quantity int '@Quantity'
)


EXEC sp_xml_removedocument @hDoc
GO
The result of the above query can be seen in the image below. You can see all the customer information and their orders along with ProductID and Quantity from each order placed.
The result of the above query  
 
 
===============================================================
Update Query:
SELECT * FROM T
UPDATE T
SET XmlCol =(
SELECT * FROM OPENROWSET(
   BULK 'C:\SampleFolder\SampleData3.txt',
           SINGLE_BLOB
) AS x
)
WHERE IntCol = 1;
GO
 
 
 

Specification for SQL Server 2008,R2 and 2012

The following tables specify the maximum sizes and numbers of various objects defined in SQL Server 2012 components, and compared against the maximum sizes and number of various objects defined in SQL Server 2008 and SQL Server 2008 R2 components.
Database Engine Objects
The following table specifies the maximum sizes and number of various objects defined in SQL Server databases or referenced in Transact-SQL statements.
Maximum Sizes / Numbers SQL Server (32-bit)
SQL Server Database Engine ObjectSQL Server 2008SQL Server 2008 R2SQL Server 2012
Batch size65,536 * Network Packet Size65,536 * Network Packet Size65,536 * Network Packet Size
Bytes per short string column8,0008,0008,000
Bytes per GROUP BY ORDER BY8,0608,0608,060
Bytes per index key900900900
Bytes per foreign key900900900
Bytes per primary key900900900
Bytes per row8,0608,0608,060
Bytes in source text of a stored procedure.Lesser of batch size or 250 MBLesser of batch size or 250 MBLesser of batch size or 250 MB
Bytes per VARCHAR(MAX), VARBINARY(MAX),XML, TEXT, or IMAGE column2^31-12^31-12^31-1
Characters per NTEXT or NVARCHAR(MAX) column2^30-12^30-12^30-1
Clustered indexes per table111
Columns in GROUP BY, ORDER BYLimited only by number of bytesLimited only by number of bytesLimited only by number of bytes
Columns or expressions in a GROUP BY WITH CUBE or WITH ROLLUP statement101010
Columns per index key161616
Columns per foreign key161616
Columns per primary key161616
Columns per nonwide table1,0241,0241,024
Columns per wide table30,00030,00030,000
Columns per SELECT statement4,0964,0964,096
Columns per INSERT statement4,0964,0964,096
Connections per clientMaximum value of configured connectionsMaximum value of configured connectionsMaximum value of configured connections
Database size524,272 terabytes524,272 terabytes524,272 terabytes
Databases per instance of SQL Server32,76732,76732,767
Filegroups per database32,76732,76732,767
Files per database32,76732,76732,767
File size (data)16 terabytes16 terabytes16 terabytes
File size (log)2 terabytes2 terabytes2 terabytes
Foreign key table references per table253253253
Identifier length (in characters)128128128
Instances per computer50 instances on a stand-alone server for all SQL Server editions.50 instances on a stand-alone server for all SQL Server editions.50 instances on a stand-alone server for all SQL Server editions.
Length of a string containing SQL statements (batch size)65,536 * Network packet size65,536 * Network packet size65,536 * Network packet size
Locks per connectionMaximum locks per serverMaximum locks per serverMaximum locks per server
Locks per instance of SQL ServerUp to 2,147,483,647Up to 2,147,483,647Up to 2,147,483,647
Nested stored procedure levels323232
Nested subqueries323232
Nested trigger levels323232
Nonclustered indexes per table999999999
Number of distinct expressions in the GROUP BY clause when any of the following are present: CUBE, ROLLUP, GROUPING SETS, WITH CUBE, WITH ROLLUP323232
Number of grouping sets generated by operators in the GROUP BY clause4,0964,0964,096
Parameters per stored procedure2,1002,1002,100
Parameters per user-defined function2,1002,1002,100
REFERENCES per table253253253
Rows per tableLimited by available storageLimited by available storageLimited by available storage
Tables per databaseLimited by number of objects in a databaseLimited by number of objects in a databaseLimited by number of objects in a database
Partitions per partitioned table or index1,0001,00015,000
Statistics on non-indexed columns30,00030,00030,000
Tables per SELECT statementLimited only by available resourcesLimited only by available resourcesLimited only by available resources
Triggers per tableLimited by number of objects in a database.Limited by number of objects in a database.Limited by number of objects in a database.
Columns per UPDATE statement (Wide Tables)4,0964,0964,096
User connections32,76732,76732,767
XML Indexes249249249
SQL Server Utility Objects
The following table specifies the maximum sizes and number of various objects that were tested in the SQL Server Utility.
Maximum Sizes / Numbers SQL Server (32-bit)
SQL Server Utility ObjectSQL Server 2008SQL Server 2008 R2SQL Server 2012
Computers (physical computers or virtual machines) per SQL Server Utility100100100
Instances of SQL Server per computer555
Total number of instances of SQL Server per SQL Server Utility200200200
User databases per instance of SQL Server, including data-tier applications505050
Total number of user databases per SQL Server Utility1,0001,0001,000
File groups per database111
Data files per file group111
Log files per database111
Volumes per computer333
SQL Server Data-Tier Application Objects
The following table specifies the maximum sizes and number of various objects that were tested in the SQL Server data-tier applications (DAC).
Maximum Sizes / Numbers SQL Server (32-bit)
SQL Server DAC ObjectSQL Server 2008SQL Server 2008 R2SQL Server 2012
Databases per DAC111
Objects per DACLimited by the number of objects in a database, or available memory.Limited by the number of objects in a database, or available memory.Limited by the number of objects in a database, or available memory.
SQL Server Replication Objects
The following table specifies the maximum sizes and number of various objects defined in SQL Server Replication.
Maximum Sizes / Numbers SQL Server (32-bit)
SQL Server Replication ObjectSQL Server 2008SQL Server 2008 R2SQL Server 2012
Articles (merge publication)256256256
Articles (snapshot or transactional publication)32,76732,76732,767
Columns in a table (merge publication)246246246
Columns in a table (SQL Server snapshot or transactional publication)1,0001,0001,000
Columns in a table (Oracle snapshot or transactional publication)995995995
Bytes for a column used in a row filter (merge publication)1,0241,0241,024
Bytes for a column used in a row filter (snapshot or transactional publication)8,0008,0008,000

ANROID Apps in .Net

If you love C# and want to create an Android application using that language then you have to thank Xamarin as they created this great Cross Platform development tool which enables developers to develop iOS and Android apps in C# language. 
If you love C# and want to create an Android application using that language then you have to thank Xamarin as they created this great Cross Platform development tool which enables developers to develop iOS and Android apps in C# language. I tried developing before in Android but I did not like the experience in using the available IDE, as its slow and resource hungry, so I gave up. A couple of years after that I attended TechEd NZ 2013 and was introduced to this wonderful platform called Xamarin.
Xamarin is offered in different licenses from free to enterprise levels but for not I will be using the starter version which is the free version. It includes the Xamarin Studio which is great start for those who want to try out creating their first apps for Android, they also offer a Business license which lets you develop in Visual Studio so you can use that rich experience similar to developing Web Apps or Windows Apps, then they have this Enterprise which contains everything. For now lets see what the free stuff can offer, I did a simple project which I will be discussing below and it looks very promising, I love it.
Like what I said above we will be using the free version so we will make this simple project by using Xamarin Studio. Now I was thinking what to do, I don’t want to create the boring "Hello World!" demo so what I will be developing is a simple calculator which acts like a normal desk calculator. Most of the calculator projects online regardless its C#, VB.Net developed as Windows
forms does not act like a normal desk calculator where you can continuously perform operations and deliver results through the screen, you can’t even change operations along the way, so I decided I will make this one and I accepted my own challenge.
Lets start! First you need to download Xamarin at https://store.xamarin.com/, while installing it will ask you to download as well prerequisites but is you are a developer most or all of them are already set up in your machine.
Once its downloaded you’re ready to roll!
Fire up Xamarin Studio and select new Solution then Android Application, give it a solution name and in this case we use "Calculator".
Once all ok you will see the IDE which is like a cross between Visual Studio and Eclipse, it has intellisense and fancy text colours and highlighting.
You will notice if you go to the Resources\layout they the UI is in a file called Main.axml which is a "Hello World" template.
At this point we are more interested on the 2 files on the solution, that layout and the MainActivity.cs where we will be doing our coding.
First lets design you calculator, you need to go to that Main.axml and start coding, you will notice its like Windows form where you can drag and drop items from the Toolbox on the right, it will also have its property window on the bottom left.
Were not interested with the dragging and dropping part so let’s go the code behind (you can control it more), so hit that Source tab below the UI beside the content source. First thing you will notice is that it is in XML format, if you’re so used to drag and drop or HTML coding then you need a bit of learning here specially the layouts.
Common layouts used are Linear Layout, Relative Layout, List View and Grid View. To see how each of them would look like here is an illustration
Linear Layout – you can organize objects in either horizontal or vertical rows.
Relative Layout – specify the location of child objects relative to each other. For example object A is placed on the left of object B or it can be aligned to a parent.
List View – Displays it in a scrolling single column list.
Grid View – Displays it in a scrolling grid view of columns and rows.
Now lets start designing, for this project we will using a mix of Linear and Relative. Copy and Paste the code below then I will give you some explanation of what it does.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
  <EditText
      android:inputType="number"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:id="@+id/resultText" />
  <LinearLayout
android:id="@+id/wrapper0"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/resultText"
android:weightSum="1.0" >
    <Button
        android:text="Clear"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:id="@+id/buttonClear"
        android:layout_weight=".25" />
  </LinearLayout>
  <LinearLayout
android:id="@+id/wrapper1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wrapper0"
android:weightSum="1.0" >
    <Button
        android:text="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:id="@+id/button1" />
    <Button
        android:text="2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button1"
        android:layout_alignTop="@+id/button1"
        android:layout_weight=".25"
        android:id="@+id/button2" />
    <Button
        android:text="3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button2"
        android:layout_alignTop="@+id/button2"
        android:layout_weight=".25"
        android:id="@+id/button3" />
    <Button
        android:text="+"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button3"
        android:layout_alignTop="@+id/button3"
        android:layout_weight=".25"
        android:id="@+id/buttonAdd" />
  </LinearLayout>
  <LinearLayout
android:id="@+id/wrapper2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wrapper1"
android:weightSum="1.0" >
    <Button
        android:text="4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/wrapper2"
        android:layout_weight=".25"
        android:id="@+id/button4" />
    <Button
        android:text="5"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button4"
        android:layout_alignTop="@+id/button4"
        android:layout_weight=".25"
        android:id="@+id/button5" />
    <Button
        android:text="6"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button5"
        android:layout_alignTop="@+id/button5"
        android:layout_weight=".25"
        android:id="@+id/button6" />
    <Button
        android:text="-"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button6"
        android:layout_alignTop="@+id/button6"
        android:layout_weight=".25"
        android:id="@+id/buttonSubtract" />
  </LinearLayout>
  <LinearLayout
android:id="@+id/wrapper3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wrapper2"
android:weightSum="1.0" >
    <Button
        android:text="7"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/wrapper3"
    android:layout_weight=".25"
        android:id="@+id/button7" />
    <Button
        android:text="8"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button7"
        android:layout_alignTop="@+id/button7"
        android:layout_weight=".25"
        android:id="@+id/button8" />
    <Button
        android:text="9"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button8"
        android:layout_alignTop="@+id/button8"
        android:layout_weight=".25"
        android:id="@+id/button9" />
    <Button
        android:text="x"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button9"
        android:layout_alignTop="@+id/button9"
        android:layout_weight=".25"
        android:id="@+id/buttonMultiply" />
  </LinearLayout>
  <LinearLayout
android:id="@+id/wrapper4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wrapper3"
android:weightSum="1.0" >
    <Button
        android:text="(-)"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button7"
        android:layout_weight=".25"
        android:id="@+id/buttonNegative" />
    <Button
        android:text="0"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/buttonNegative"
        android:layout_alignTop="@+id/buttonNegative"
        android:layout_weight=".25"
        android:id="@+id/button0" />
    <Button
        android:text="."
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button0"
        android:layout_alignTop="@+id/buttonNegative"
        android:layout_weight=".25"
        android:id="@+id/buttonDot" />
    <Button
        android:text="/"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/buttonDot"
        android:layout_alignTop="@+id/buttonDot"
        android:layout_weight=".25"
        android:id="@+id/buttonDivide" />
  </LinearLayout>
  <Button
      android:text="="
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_below="@+id/wrapper4"
      android:id="@+id/buttonEquals" />
</RelativeLayout>
Most of the objects are created similar to an HTML tags like and <EditText>. Also like HTML Tags they will have properties and the common ones we used are:
  • orientation – this sets our object orientation either vertical or horizontal.
  • layout_width – fill_parent will fill depending on the parent with, you can also specify a with by using something like 200dp. If you want to use percentage use 0dp but we will be indicating percentage on layout_weight.
  • layout_height – similar to layout_width.
  • layout_weight – this indicated the percentage you will use on the width.
  • id – identifier to the object.
  • layout_toRightOf – this indicates you will place this object to the right of what object Id.
  • layout_alignTop – this aligns your object similar to what object Id.
  • layout_below – this will place your object below the object Id.
other elements would sound similar to .Net object properties. Now click your content tab to see how it looks. It should be something like this
Now you have your UI, you need to start coding in C#, so go to your MainActivity.cs
To display the layout you need to do this.
SetContentView (Resource.Layout.Main);
Then you will notice that objects are not natively available in code, you cant do something like this
resultText.Text = "";
you need to find it like how you find objects but ID in a grid during the ASP.Net days. To do it here is a sample for button1
Button button1 = FindViewById<Button> (Resource.Id.button1);
Now you have your button1, you can assign a delegate and define what it should do when you click
button1.Click += delegate {
//Your stuff here
};   
Other than that you’re good to go, everything should be easy. So for the full code just copy and paste the one below, it’s an operational calculator.
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace SampleAndroidApp
{
    [Activity(Label = "Ray's Calculator", MainLauncher = true)]
    public class MainActivity : Activity
    {
        private enum Operation { Addition, Subtraction, Division, Multiplication };
        private enum LastKeyInput { Digit, Operator, Equal, DecimalPoint, Sign }

        decimal? digitMemory = null;
        decimal? totalMemory = null;

        Operation? operationMemory = null;

        LastKeyInput? lastKeyInput = LastKeyInput.Digit;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // Get our button from the layout resource,
            // and attach an event to it
            Button button1 = FindViewById(Resource.Id.button1);
            Button button2 = FindViewById(Resource.Id.button2);
            Button button3 = FindViewById(Resource.Id.button3);
            Button button4 = FindViewById(Resource.Id.button4);
            Button button5 = FindViewById(Resource.Id.button5);
            Button button6 = FindViewById(Resource.Id.button6);
            Button button7 = FindViewById(Resource.Id.button7);
            Button button8 = FindViewById(Resource.Id.button8);
            Button button9 = FindViewById(Resource.Id.button9);
            Button button0 = FindViewById(Resource.Id.button0);
            Button buttonDot = FindViewById(Resource.Id.buttonDot);
            Button buttonNegative = FindViewById(Resource.Id.buttonNegative);

            EditText resultText = FindViewById(Resource.Id.resultText);

            Button buttonAdd = FindViewById(Resource.Id.buttonAdd);
            Button buttonSubtract = FindViewById(Resource.Id.buttonSubtract);
            Button buttonMultiply = FindViewById(Resource.Id.buttonMultiply);
            Button buttonDivide = FindViewById(Resource.Id.buttonDivide);
            Button buttonEquals = FindViewById(Resource.Id.buttonEquals);
            Button buttonClear = FindViewById(Resource.Id.buttonClear);

            buttonNegative.Click += delegate
            {
                //handles if negative sign is the first input after calculation
                if (lastKeyInput != LastKeyInput.Digit && lastKeyInput != LastKeyInput.DecimalPoint && lastKeyInput != LastKeyInput.Sign)
                {
                    resultText.Text = "-";
                    lastKeyInput = LastKeyInput.Sign;
                    return;
                }
                //handles multiple negative sign
                if (!resultText.Text.Contains("-"))
                {
                    resultText.Text = "-" + digitMemory.ToString();
                    lastKeyInput = LastKeyInput.Sign;
                }

            };
            buttonDot.Click += delegate
            {
                //handles if decimal point is the first input after calculation
                if (lastKeyInput != LastKeyInput.Digit && lastKeyInput != LastKeyInput.DecimalPoint && lastKeyInput != LastKeyInput.Sign)
                {
                    resultText.Text = ".";
                    lastKeyInput = LastKeyInput.DecimalPoint;
                    return;
                }
                //handles multiple decimal point
                if (!resultText.Text.Contains("."))
                {
                    resultText.Text = digitMemory.ToString() + ".";
                    lastKeyInput = LastKeyInput.DecimalPoint;
                }

            };
            button1.Click += delegate
            {
                //Renders Text on Screen
                RenderCurrentValue(resultText.Text, "1");
                resultText.Text = digitMemory.ToString();

                //Perform calculation based on current operator
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button2.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "2");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button3.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "3");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button4.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "4");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button5.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "5");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button6.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "6");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button7.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "7");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button8.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "8");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button9.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "9");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button0.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "0");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            buttonClear.Click += delegate
            {
                resultText.Text = "";
                ResetMemory();
            };

            buttonAdd.Click += delegate
            {
                if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.Operator)
                {
                    operationMemory = Operation.Addition;
                }
                resultText.Text = totalMemory.ToString();
                lastKeyInput = LastKeyInput.Operator;
            };

            buttonSubtract.Click += delegate
            {
                if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.Operator)
                {
                    operationMemory = Operation.Subtraction;
                }
                resultText.Text = totalMemory.ToString();
                lastKeyInput = LastKeyInput.Operator;
            };

            buttonMultiply.Click += delegate
            {
                if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.Operator)
                {
                    operationMemory = Operation.Multiplication;
                }
                resultText.Text = totalMemory.ToString();
                lastKeyInput = LastKeyInput.Operator;
            };

            buttonDivide.Click += delegate
            {
                if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.Operator)
                {
                    operationMemory = Operation.Division;
                }
                resultText.Text = totalMemory.ToString();
                lastKeyInput = LastKeyInput.Operator;
            };

            buttonEquals.Click += delegate
            {
                lastKeyInput = LastKeyInput.Equal;
                resultText.Text = totalMemory.ToString();
                ResetMemory();
            };

        }

        private void Calculate()
        {
            if (operationMemory != null)
            {
                switch (operationMemory)
                {
                    case Operation.Addition:
                        if (totalMemory == null)
                        {
                            //Handles first entry
                            totalMemory = digitMemory;
                        }
                        else
                        {
                            totalMemory = totalMemory + digitMemory;
                        }
                        lastKeyInput = LastKeyInput.Operator;
                        break;

                    case Operation.Subtraction:
                        if (totalMemory == null)
                        {
                            //Handles first entry
                            totalMemory = digitMemory;
                        }
                        else
                        {
                            totalMemory = totalMemory - digitMemory;
                        }
                        lastKeyInput = LastKeyInput.Operator;
                        break;

                    case Operation.Multiplication:
                        if (totalMemory == null)
                        {
                            //Handles first entry
                            totalMemory = digitMemory;
                        }
                        else
                        {
                            totalMemory = totalMemory * digitMemory;
                        }
                        lastKeyInput = LastKeyInput.Operator;
                        break;

                    case Operation.Division:
                        if (totalMemory == null)
                        {
                            //Handles first entry
                            totalMemory = digitMemory;
                        }
                        else
                        {
                            totalMemory = totalMemory / digitMemory;
                        }
                        lastKeyInput = LastKeyInput.Operator;
                        break;
                }
            }
            else
            {

                totalMemory = digitMemory;

            }
        }

        private void RenderCurrentValue(string currentRenderedValue, string character)
        {
            //display multiple digits
            if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.DecimalPoint || lastKeyInput == LastKeyInput.Sign)
            {
                digitMemory = decimal.Parse(currentRenderedValue + character);
            }
            else
            {
                digitMemory = decimal.Parse(character);
            }
        }

        private void ResetMemory()
        {
            totalMemory = null;
            digitMemory = null;
            operationMemory = null;
            lastKeyInput = LastKeyInput.Digit;
        }
    }

}
Just a side note : You might notice Calculate happens on each digit press, this makes sure you have a running total even before you hit the operator. The operator buttons will just store the current operator needed for your next digit press.
Other than that you are now all good to go, just hit run
It will now ask you for a device, if you don’t have an emulator yet then you can create one, choose create emulator then hit OK.
Click New
Then I suggest create something similar to a device you have, so you can play around with it on your device.
Once created hit start, then launch
You will now see it will start, and it will also show you any errors it encounter.
Once started go back to Xamarin and choose the device you want your app to run on, in this case your newly created emulator, it will then be automatically deployed on the emulator.
You will then see the progress on the middle top part of the IDE.
Then on your emulator