Wednesday, June 15, 2022

SOLVED! using insert returning into with Oracle.ManagedDataAccess.Core

I spent several hours with a strange behaviour in Oracle.ManagedDataAccess.Core in my C# web project in visual studio 2022. The version of that package was 3.21.61.

I wanted to insert data into a table and return the rowid for the inserted record for further use in my code. For that I wanted to use the "insert returning into" - clause in oracle sql.

I found quite a lot of examples explaining how to do this but it didn't work like it was supposed to; rowid returned always was blank (empty string). I tried all the solutions that other had proposed like use a pl/sql block around the insert statement and others proposed using ReturnValue instead of Output for the direction of the parameter.

At first I tried creating the parameter like below and it then returned just an empty string:

cmd.Parameters.Add("P_ROWID", OracleDbType.NVarchar2, ParameterDirection.Output);

The thing that fooled me in the wrong directions while looking for the correct solution was that using this line didn't return an error at all! Getting an error would have helped a lot!

So the solution was to add two more parameters to the Parameters.Add-statement!

The working code that is returning a correct rowid:

// testClass
[TestClass()]
public class testReturningTests
{
  private static testReturning tr = new testReturning();

  [TestMethod()]
  public void queryTest()
  {
    Console.WriteLine(tr.query());
  }
}



// program
using System.Data;

using Oracle.ManagedDataAccess.Client;

namespace test.Data

{

  public class testReturning

  {

    public string query()

    {

      OracleConnection con = new OracleConnection("User ID=TEST_USER;"+
           "Password=testpassword; Data Source=(DESCRIPTION=(ADDRESS="+
           "(PROTOCOL=tcp)(HOST=servername.mydomain.com)(PORT=1521))"+
           "(CONNECT_DATA=(SERVICE_NAME=mydb)))");

      con.Open();

      string sql = "insert into countrycodes " +
                    " (COUNTRYCODE, COUNTRYNAME) " +
                    " values ( :P_COUNTRYCODE,: P_COUNTRYNAME) " +
                    " returning rowidtochar(rowid) into :P_ROWID";

      OracleCommand cmd = new OracleCommand(sql, con);

      cmd.BindByName = true;

      cmd.Parameters.Add("P_COUNTRYCODE ", OracleDbType.NVarchar2, "SE",                                       ParameterDirection.Input);

      cmd.Parameters.Add("P_COUNTRYNAME ", OracleDbType.NVarchar2,"SWEDEN",                                   ParameterDirection.Input);

      cmd.Parameters.Add("P_ROWID", OracleDbType.NVarchar2, 64, null,                                          ParameterDirection.Output);

      cmd.ExecuteNonQuery();

      return cmd.Parameters["P_ROWID"].Value.ToString();

    }

  }

}

Wednesday, January 17, 2018

My first game released: Gravity game free !


Use your skill to take control of gravity and save the solar systems in the galaxy from the dark threat in this free game.

Control the comets by turning on and off the gravity on the planets, let them orbit and crasch into the black hole before it is late.

Are you ready to control the forces of space to win in all the levels in this clever game.

Playing with gravity has never been more fun!


image

https://play.google.com/store/apps/details?id=com.qarallax.gravity

Tuesday, April 4, 2017

Unity3d creating a cube in c# with text on each side

I am currently exploring the power of the Unity3d developer environment. It really amazes me! Really fun and easy to get started and a lot of fun coding!
I wanted to create a cube with letters/text on each side. The text should be possible to manipulate dynamically so premade textures was out of the question.
First I thought that it couldn’t be so hard. I soon found out that many before me had struggled with the same problem.
I tried the 3dtext but it had a problem with the text showing througt other objects. Not very nice!
My solution is to use the UI and its text possibilities.
image
Create a method that takes the size of the cube and the text that should be printed on the side:
public class scriptCube {
  static GameObject addSide (int size, string text) {

First we create a canvas-object to hold the UI:

    GameObject mainObj = new GameObject();
    Canvas canvasObj = mainObj.AddComponent<Canvas>();
    canvasObj.renderMode = RenderMode.WorldSpace;

Then we create a rawimage-object and we connect it to the parent object:

    GameObject childObj2 = new GameObject ();
    RawImage rawimageObj = childObj2.AddComponent<RawImage>();
    rawimageObj.rectTransform.SetSizeWithCurrentAnchors
         (RectTransform.Axis.Horizontal, size);
    rawimageObj.rectTransform.SetSizeWithCurrentAnchors
         (RectTransform.Axis.Vertical, size);
    rawimageObj.color = Color.yellow;
    childObj2.transform.SetParent(mainObj.transform,false);


We also have to create the text-object and connect it to the parent object:
    GameObject childObj1 = new GameObject ();
    Text textObj = childObj1.AddComponent<Text>();
    textObj.font = (Font)Resources.GetBuiltinResource
        (typeof(Font), "Arial.ttf");;
    textObj.text = text;
    textObj.alignment = TextAnchor.MiddleCenter;
    textObj.enabled = true;
    textObj.fontSize = (int) (size*0.8);
    textObj.color = Color.black;
    textObj.rectTransform.SetSizeWithCurrentAnchors
        (RectTransform.Axis.Horizontal, size);
    textObj.rectTransform.SetSizeWithCurrentAnchors
        (RectTransform.Axis.Vertical, size);
    childObj1.transform.SetParent(mainObj.transform,false);


    return mainObj;
  }
}

Now that we have a method that creates panels with rawimages and text on it we need to put it all together with a method that create all sides of the cube and positions them correctly in the worldSpace.
The following code creates the six sides of the cube and positions and turns them individually.
I know this surely could be made in some more effective ways but this works for now.
public static GameObject createCube (string name, int size) {

  GameObject mainObj = new GameObject();
  mainObj.name = name;

  GameObject side1 = addSide (size, "1");
  side1.transform.SetParent (mainObj.transform);
  side1.transform.position = new Vector3(0,0,-size/2);
  side1.transform.rotation = Quaternion.Euler(0,0,0);

  GameObject side2 = addSide (size, "6");
  side2.transform.SetParent (mainObj.transform);
  side2.transform.position = new Vector3(0,0,size/2);
  side2.transform.rotation = Quaternion.Euler(0,180,0);

  GameObject side3 = addSide (size, "3");
  side3.transform.SetParent (mainObj.transform);
  side3.transform.position = new Vector3(0,-size/2,0);
  side3.transform.rotation = Quaternion.Euler(90,0,0);

  GameObject side4 = addSide (size, "4");
  side4.transform.SetParent (mainObj.transform);
  side4.transform.position = new Vector3(0,size/2,0);
  side4.transform.rotation = Quaternion.Euler(90,0,0);

  GameObject side5 = addSide (size, "2");
  side5.transform.SetParent (mainObj.transform);
  side5.transform.position = new Vector3(-size/2,0,0);
  side5.transform.rotation = Quaternion.Euler(0,90,0);

  GameObject side6 = addSide (size, "5");
  side6.transform.SetParent (mainObj.transform);
  side6.transform.position = new Vector3(size/2,0,0);
  side6.transform.rotation = Quaternion.Euler(0,270,0);

  mainObj.transform.rotation = Quaternion.Euler(45,45,45);

  return mainObj;
}

Add a call to the newly created method to get it all started:

void Start () {
  scriptCube scriptcube = new scriptCube ();
  GameObject cube = scriptCube.createCube ("Cube", 40);
}

To turn the scene camera to view the cube and rotate around it just add this to the camera script:
private GameObject target;
void Update () {
  target = GameObject.Find ("Cube");
  if (target != null) {
    transform.LookAt (target.transform);
    transform.Translate (Vector3.right * Time.deltaTime * 60);
  }
}

Happy hacking and have a nice day!



Sunday, March 5, 2017

Oracle: how to page / paging result in select

 

If You want to to a fast paging in your application the best way is sometimes to let the database do the job. You could of course let the appication server select all rows and then pick out the one you want but that could be a huge job if the query gives a extensive recordset.

Paging in Oracle is not as easy as one could think. If you would like your query to return lets say 100 rows with the start at row 1300 you could use the following SQL statement:


select * from (
  select rowum as rn, b.*
    from (select a.columnName1, a.columnName2
            from tableName a
           order by a.columnName1) b
        ) c
    where c.rn between 1300 and 1300 + 100;

Have a nice day and happy SQL-hacking!

Sunday, February 26, 2017

Converting C-64 Basic program to text file

 

In the CCS64 emulator you can save your Basic program as a .prg-file in the PCs filesystem. The .prg i quite unreadable (not human readable) and I was looking for a way to get the commandlines into text to be able to put it into for examle this blog.

How do one get the Basic program listing out of the C64 emulator? One way is through this fine little program:

image

Download link: https://www.commodoreserver.com/Downloads.asp

 

Just unzip the file into a folder and start a DOS-prompt, start the exe and you get the following helptext:

-------------------------------------------------------------------------------
Loads Commodore 64 BASIC programs and converts them between various formats.
Contact: c64List@gmail.com
Automatically determines the format to load by the file extension.
Loads these file types
   prg  (prg C64 format: 2 address bytes followed by program data
   p00  (same as prg, but contains filename data as well)
   txt  (prg/p00 files detokenized and converted to text by C64List
-------------------------------------------------------------------------------
Syntax:
        c64list <input filename> [control parameters]

where control parameters include:
        -ovr            overwrite an existing file
        -prg[:name]     save in .prg format
        -p00[:name]     save in .p00 format (Only p00 is supported--not 01-99)
        -hex[:name]     save in an ASCII hex dump format
        -asm[:name]     save in a memory-disassembled format
        -txt[:name]     save untokenized BASIC code in a text format
        -lbl[:name]     save, same as -txt, except convert to label format

        -verbose[:list] output additional information during conversion
        -tokenizer:name load a tokenizer map file
        -b4             load the BASIC 4.0 tokenizer map file
        -b7             load the BASIC 7.0 tokenizer map file
        -alpha:<mode>   where <mode> can be normal|upper|lower|invert
        -range:n1-n2    for .hex/.asm, only output indicated range
        -con            for .hex/.asm, dump output to screen
        -sym            dump the asm symbol table to screen
        -labels         dump the list of labels to screen

Additionally, when converting to and from text files:
        -crunch (from text) removes unquoted space
        -crunch (to text) adds spacing for readability
        -crsr   (to text) preserves binary cursor codes
        -rem    remove all REM statements

For the output format parameters, if you specify
  <nothing> the input name is used, but the proper extension is applied
  :<name> the specified name is used

 

Convert to text-format:

CMD> C64List.exe C:\temp\Slimy.PRG  -txt:c:\temp\Slimy.txt
-------------------------------------------------------------------------------
                C64List (v3.03) Copyright 2012 by Jeff Hoag
-------------------------------------------------------------------------------
Encountered: 0 Errors; 0 Warnings
C64List finished.

Now I have all the Basic-lines in plain text and I’m able to paste it into here:

0 IFOP=0THENOP=1:LOAD"-SLIMY",8,1
1 POKE53272,24:GOSUB13000:W=53281:POKEW,0:POKEW-1,0
2 POKE53270,216:POKEW+2,7:POKEW+3,15
3 DIMA(500):M=67:R=66:GOTO5000
4 RUN                              
5 LE=3:A=1024:B=55296:P=1
6 X=500:J=65:S=32:X=A+X:REMA(1)=X
8 POKE54296,15:O=54273:POKEO+4,96:POKEO+5,96:POKEO+3,0:POKEO+3,33
10 FORI=40TO79:POKEA+I,M:POKEB+I,7:POKEO,I*2:NEXT
20 FORI=119TO959STEP40:POKEA+I,M:POKEB+I,7:POKEO,I/4:NEXT
30 FORI=80TO921STEP40:POKEA+I,M:POKEB+I,7:POKEO,I/9:NEXT
40 FORI=960TO999:POKEA+I,M:POKEB+I,7:POKEO,I-960:NEXT:POKEO,0
50 FORI=1TO3:GOSUB70:NEXT:GOTO100
69 
70 C=INT(80+960*RND(1)):IFC+A=XTHEN70
80 IFPEEK(A+C)<>STHEN70
85 PRINT"{home}SCORE:"PO;TAB(25)"HI-SCORE:"PO(0)
90 POKEA+C,R:POKEB+C,13:RETURN
98 
100 LE1=LE:FORQ=1TOLE1:POKEA(Q),S:A(Q)=X:POKEX,J:POKEB-A+X,14
2010 T=PEEK(197):IFT=9ANDP<>40THENP=-40
2020 IFT=12ANDP<>-40THENP=40
2030 IFT=10ANDP<>1THENP=-1
2040 IFT=13ANDP<>-1THENP=1
2050 X=X+P:F=PEEK(X):IFF<>STHENGOSUB5200
2100 IFPEEK(W+1)=245THENPOKEW+1,0:POKEW+2,5:GOTO2300
2110 POKEW+1,5:POKEW+2,0
2300 NEXT:GOTO100
2320 
4107 
5000 PRINT"{clear}{gray3}"
5010 PRINTSPC(10)"{$c4:3}{right}{$c4}{right:3}{$c4}{right}{$c4}{right:3}{$c4}{right}{$c4}{right}{$c4}"
5020 PRINTSPC(10)"{$c4}{right:3}{$c4}{right:3}{$c4}{right}{$c4:2}{right}{$c4:2}{right}{$c4}{right}{$c4}"
5030 PRINTSPC(10)"{$c4:3}{right}{$c4}{right:3}{$c4}{right}{$c4}{right}{$c4}{right}{$c4}{right}{$c4:3}"
5040 PRINTSPC(10)"{right:2}{$c4}{right}{$c4}{right:3}{$c4}{right}{$c4}{right:3}{$c4}{right:2}{$c4}{right}"
5050 PRINTSPC(10)"{$c4:3}{right}{$c4:3}{right}{$c4}{right}{$c4}{right:3}{$c4}{right:2}{$c4}{right}"
5055 PRINTSPC(10)"{lt. blue}{$c1:19}"
5060 PRINTSPC(18)"{yellow}{down:2}BY{down}"
5062 PRINTSPC(15)"ALPHA ZOFT{down:2}"
5065 PRINT"       {$d5}{$c0:24}{$c9}"
5066 PRINT"       {$dd}      INSTRUCTIONS      {$dd}"
5067 PRINT"       {$dd}                        {$dd}"
5068 PRINT"       {$dd}W=UP       {lt. green}{$c2}{yellow} 10 PTS     {$dd}"
5069 PRINT"       {$dd}Z=DOWN     {lt. green}{$c4}{yellow} WATCH OUT! {$dd}"
5070 PRINT"       {$dd}A=LEFT                  {$dd}"
5071 PRINT"       {$dd}S=RIGHT                 {$dd}"
5072 PRINT"       {$dd}                        {$dd}"
5074 PRINT"       {$dd}                        {$dd}"
5075 PRINT"       {$ca}{$c0:24}{$cb}"
5076 IFPEEK(W+1)=245THENPOKEW+1,0:POKEW+2,5:GOTO5080
5078 POKEW+1,5:POKEW+2,0
5080 FORI=1TO25:IFPEEK(197)<>60THENNEXT:GOTO5076
5100 PRINT"{clear}{down:8}":PO=0
5110 PRINTSPC(10)"GO FOR IT, SUCKER.":FORI=1TO1500:NEXT:PRINT"{clear}":GOTO5
5200 IFF=RTHENLE=LE+3:PO=PO+10:GOTO7000
5202 PRINT"{down:3}{right:13} GAME OVER !":FORI=1TO15:POKEW+3,I
5203 FORT=200TO100STEP-5:POKEO,T/I:NEXT:NEXT:POKEO,0
5210 FORI=1TO1000:NEXT:GOTO10000
7000 FORT=240TO0STEP-80:POKEO,T:NEXT
7100 IFPO/50<>INT(PO/50)THENGOSUB70:RETURN
7120 C=INT(80+960*RND(1)):IFPEEK(A+C)<>STHEN7120
7130 POKEA+C,68:POKEB+C,13:GOSUB70:RETURN
9999 
10000 POKE198,0:IFPO<=PO(9)THEN10400
10050 PRINT"{clear}{down:2}"SPC(5)"LUCKY, YOU GOT A GOOD SCORE."
10060 PRINT"{down}"SPC(7)"PLEASE ENTER YOUR NAME:{down:2}":PRINTSPC(5);
10105 OPEN1,0:INPUT#1,A$:CLOSE1:C$=LEFT$(A$,18)
10110 FORI=0TO9:IFPO>PO(I)THEN10200
10120 NEXT
10200 FORT=9TOISTEP-1:NA$(T+1)=NA$(T):PO(T+1)=PO(T):NEXT
10210 NA$(I)=C$:PO(I)=PO:GOSUB12000
10400 PRINT"{clear}"SPC(15)"{down:3}TOP 10"
10405 PRINTSPC(15)"======{down:2}"
10410 FORT=0TO9:PRINT,PO(T),NA$(T):NEXT
10430 WAIT197,32:GOTO5000
12000 OPEN8,8,8,"@8:HI-MASK1,S,W"
12010 FORI=0TO9:PRINT#8,NA$(I)
12020 PRINT#8,PO(I):NEXT:CLOSE8:RETURN
13000 OPEN8,8,8,"8:HI-MASK1,S,R"
13010 FORI=0TO9:INPUT#8,NA$(I)
13020 INPUT#8,PO(I):NEXT:CLOSE8:RETURN

Have a nice day and happy C64-hacking!

Saturday, February 25, 2017

SOLVED: publishing with Open Live Writer to Blogger 501-error

 

When pushing the Publish-button image  after writing my new post with Open Live Writer (OLW) I got the following error:

The remote server returned an error: (501) Not Implemented.

I am new to OLW so this is my first post from Open Live Writer and I have been using Google for a while so that account is old. I have used Google Picasa web and Photos for a while.

In the “Open Live Writer.log” I get the following:

OpenLiveWriter,1.11164,Fail,00027,25-Feb-2017 15:39:42.225,"System.InvalidOperationException: The file type is not registered with this application.
   at OpenLiveWriter.PostEditor.JumpList.JumpList.AppendCustomCategories()
   at OpenLiveWriter.PostEditor.JumpList.JumpList.Refresh()

Posting to Googles Blogger fails when the post includes images. I have spent som hours now googling around and trying to find solutions. Some have tried different number of images and it actually works without images which would be pointing towards the Google Photos service.

I tried opening my Google account for “less secure applications” but nu success… More googling today and I found this blog:  https://livewriterbasics.wordpress.com/
In a post a bit down the page I found what I was looking for: where do Open Live Writer store the images (which album)?

“the images are uploaded to you Google album “Windows Live Writer””

Well, I thougt I would change that to “Open Live Writer” and I went into Google Photos and created a new album called just “Open Live Writer”.

Back to OLW and voila! It uploaded my post!

image

When creating a new album in Google Photos you have to select at least one image. You can’t just create an empty album!

Have a nice day and happy blogging!

Thursday, February 23, 2017

Installing Windows Live Writer

Flickr Tags:

Please read the whole post before trying to install Windows Live Writer!

Nothing should ever be easy…  I needed a blogger program for my windows computer to make it easier to start blogging. Especially adding screenshots to the blog needed to be easier.

I thought Windows live writer should do it! But…  why should it just work!?!

I went to the download page:

https://www.microsoft.com/sv-se/download/details.aspx?id=8621

image

pressed Download and started the installer:

clip_image001

Couldn’t install programs
please try installing windows live programs again
Error: OnCatalogResult: 0x80190194
Next steps: n unknown error occured

Well, there’s a solution for this, download the offline installer for Windows Live Writer 2015:

http://g.live.com/1rewlive5-all/en/wlsetup-all.exe??WLXID=4853586d-18bf-48db-862a-f7751676bdc2&RID=001d45fe68b&TID=1443488579712&lid=

 

image

Choose the programs to install

clip_image002

Deselect everythnig except Writer

 

image

image

Here’s where I got stuck! I found some tips about lowering the secutiry on the google account allowing more unsecure applications too connect:

https://www.google.com/settings/security

image

well, it did not work! Someone wrote that Writer didn’t support Blogger anymore and perhaps is that correct!

Uninstall and try another application called Open Live Writer:

http://openlivewriter.org/

image

Easy to install and support for Googles Blogger and login through Google account!

This post is my first with Open Live Writer and I can assure You that it’s not the last one!

Have a nice day!