{"id":13652873,"url":"https://github.com/pljson/pljson","last_synced_at":"2025-12-17T00:48:06.035Z","repository":{"id":2462739,"uuid":"13413875","full_name":"pljson/pljson","owner":"pljson","description":"PL/JSON is a generic JSON object written in PL/SQL. Using PL/SQL object syntax, users instantiate a JSON object and then add members, arrays and additional JSON objects. This object type can store JSON data, in Oracle, persistently.","archived":false,"fork":false,"pushed_at":"2024-06-26T18:47:52.000Z","size":2674,"stargazers_count":458,"open_issues_count":5,"forks_count":180,"subscribers_count":57,"default_branch":"develop_v3","last_synced_at":"2025-03-07T13:44:05.475Z","etag":null,"topics":["json","oracle","plsql","sql"],"latest_commit_sha":null,"homepage":"http://pljson.github.io/pljson/","language":"PLSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pljson.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2013-10-08T13:17:56.000Z","updated_at":"2025-03-03T09:43:30.000Z","dependencies_parsed_at":"2024-03-08T13:30:49.466Z","dependency_job_id":null,"html_url":"https://github.com/pljson/pljson","commit_stats":{"total_commits":278,"total_committers":22,"mean_commits":"12.636363636363637","dds":0.7158273381294964,"last_synced_commit":"5927d853caee13fc8ddcc4248be7bfa4cac0fd13"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pljson%2Fpljson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pljson%2Fpljson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pljson%2Fpljson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pljson%2Fpljson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pljson","download_url":"https://codeload.github.com/pljson/pljson/tar.gz/refs/heads/develop_v3","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250365665,"owners_count":21418725,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","oracle","plsql","sql"],"created_at":"2024-08-02T02:01:03.590Z","updated_at":"2025-12-17T00:48:06.004Z","avatar_url":"https://github.com/pljson.png","language":"PLSQL","readme":"\u003cimg alt=\"language\" src=\"https://img.shields.io/badge/language-PLSQL%2FSQL-brightgreen?labelColor=orange\"\u003e\n\n\u003cimg alt=\"platform\" src=\"https://img.shields.io/badge/platform-Oracle-red?labelColor=brightgreen\"\u003e\n\n\u003cimg alt=\"version\" src=\"https://img.shields.io/github/package-json/v/pljson/pljson/develop_v3?color=orange\u0026label=version\u0026labelColor=brightgreen\"\u003e\n\n# PL/JSON\n\n**PL/JSON** provides packages and APIs for dealing with JSON formatted data within PL/SQL code.\nGeneral information about JSON is available at http://www.json.org.\n\n## Latest release 3.7.1 (2024-03-06)\n\n### What's new\nNow **pljson_dyn** has the Oracle ORDS feature that when a column alias starts with **{}**\nthen the column is assumed to be a json string and it's not escaped so that is merges seamlessly within the surrounding JSON\n(the initial **{}** is removed from the result element name)\n\nThis release contains a small but important improvement.\n\nIt allows use of \"\\\u003cany character named field\\\u003e\" (quoted field name) in a path\nand does not accept anymore spaces in field names or field names starting with digit.\n(this is not yet accepted in ```json_table``` but this is a planned next step)\n\nPath expressions are now compatible with Oracle Basic SQL/JSON Path Expression Syntax\nbut excluding the optional filter expression and the optional function step at end.\n\nmore details in [Updated definition of json path expression syntax accepted by PL/JSON](#updated-definition-of-json-path-expression-syntax-accepted-by-PLJSON)\n\n## This is version 3\nYou should move to version 3. It's cleaner and faster.\n\nThe main difference with version 2 is in that now there is an object type for each json element.\nThe types are\n\n|type|use|\n|:---|:---|\n|**pljson** | for json object|\n|**pljson_list** | for json array|\n|**pljson_string** | for json string|\n|**pljson_number** | for json number|\n|**pljson_bool** | for json true/false|\n|**pljson_null** | for json null|\n\nand all these types descend from type **pljson_element**\n\nwhile in version 2 the object type pljson_value is a container that contains one of\nstring, number, boolean true/false, null, pljson or pljson_list\n\nThis is a cleaner design and the benefit is easier coding and faster and more memory efficient code.\n\nIn the JSON standard, a document consists of \"value(s)\"\nso we should name the parent of all objects pljson_value\nhowever this name has been so much ingrained with version 1 and version 2\nthat it is felt that a new name should be used and so the parent is now named pljson_element.\nOld code uses a lot pljson_value() constructors while new code has no such constructors\nbut instead has specific constructors for string, number, etc.\nand so code compatibility could not be maintained even if the name of pljson_value was kept.\n\nPL/JSON evolved from version 1 using sys.anydata and worked with early Oracle releases\nto version 2 where sys.anydata was removed and an object oriented design was used but\nthe object design wasn't the most appropriate one and mirrored the objects of version 1 so that\nthere was almost 100% compatibility with version 1 code.\n\nThe api changes for version 3 are few, mainly\n1. use new constructors instead of pljson_value()\n2. remove the need to call the 'to_json_value()' method\n3. optionally use many new helpful methods for easier coding\n\nBoth PL/JSON version 3 and version 2 will be maintained together for quite a long time\nand there will be effort that there is as much common code as possible between the two versions\nbut new features and improvements will be delivered first to version 3.\n\n## A demo of things you can do with PL/JSON\n```\ndeclare\n  obj pljson;\n  list pljson_list;\nbegin\n\n  obj := pljson('\n    {\n      \"a\": null,\n      \"b\": 12.243,\n      \"c\": 2e-3,\n      \"d\": [true, false, \"abdc\", [1,2,3]],\n      \"e\": [3, {\"e2\":3}],\n      \"f\": {\n        \"f2\":true\n      }\n    }');\n  obj.print;\n  -- equivalent to print\n  dbms_output.put_line(obj.to_char);\n\n  -- print compact way\n  obj.print(false);\n  -- equivalent to print compact way\n  dbms_output.put_line(obj.to_char(false));\n\n  -- add to json object\n  obj.put('g', 'a little string');\n  -- remove from json object\n  obj.remove('g');\n\n  -- count of direct members in json object\n  dbms_output.put_line(obj.count);\n\n  -- test if an element exists\n  if not obj.exist('json is good') then\n    obj.put('json is good', 'Yes!');\n    if obj.exist('json is good') then\n      obj.print;\n      dbms_output.put_line(':-)');\n    end if;\n  end if;\n\n  -- you can build lists (arrays) too\n  list := pljson_list(); --fresh list;\n  list.append(pljson('{\"lazy construction\": true}'));\n  list.append(pljson_list('[1,2,3,4,5]'));\n  list.print;\n    -- empty list and nested lists are supported\n  list := pljson_list('[1,2,3,[3, []]]');\n  list.print;\n  -- count of direct members in json list\n  dbms_output.put_line(list.count);\n\n  -- you can also put json object or json lists as values\n  obj.put('nested json', pljson('{\"lazy construction\": true}'));\n  obj.put('an array', pljson_list('[1,2,3,4,5]'));\n  obj.print;\n\n  -- support for dates\n  obj.put('a date', pljson_ext.to_json_string(to_date('2017-10-21', 'YYYY-MM-DD')));\n  -- and convert it back\n  dbms_output.put_line(pljson_ext.to_date(obj.get('a date')));\n\n  obj := pljson(\n    '{\n      \"a\" : true,\n      \"b\" : [1,2,\"3\"],\n      \"c\" : {\n        \"d\" : [[\"array of array\"], null, { \"e\": 7913 }]\n      }\n    }');\n\n  -- get elements using a json path expression\n  -- pljson supports a simple dot path expression and '[n]' for arrays\n  -- it never raises an exception (null is returned instead)\n  -- arrays are 1-indexed\n  -- the empty string as path returns the entire json object\n  -- can 'get_string', 'get_number', etc.\n  dbms_output.put_line(pljson_ext.get_number(obj, 'c.d[3].e'));\n\n  -- all pljson_... objects are copies\n  -- so modification in place is difficult\n  -- but put with path can do it\n  pljson_ext.put(obj, 'c.d[3].e', 123);\n  obj.print;\n\n  -- if you provide an invalid path then an error is raised\n  -- you can, however, specify a path that doesn't exists but should be created\n  -- arrays are 1-indexed.\n  -- gaps will be filled with json null(s)\n  obj := pljson();\n  pljson_ext.put(obj, 'a[2].data.value[1][2].myarray', pljson_list('[1,2,3]'));\n  obj.print;\n  -- fill the holes\n  pljson_ext.put(obj, 'a[1]', 'filler1');\n  pljson_ext.put(obj, 'a[2].data.value[1][1]', 'filler2');\n  obj.print;\n  -- replace larger structures:\n  pljson_ext.put(obj, 'a[2].data', 7913);\n  obj.print;\n\n  obj := pljson(\n    '{\n      \"a\" : true,\n      \"b\" : [1,2,\"3\"],\n      \"c\" : {\n        \"d\" : [[\"array of array\"], null, { \"e\": 7913 }]\n      }\n    }');\n  obj.print;\n\n  -- remove element\n  pljson_ext.remove(obj, 'c.d[3].e');\n  obj.print;\n  -- remove array of array\n  pljson_ext.remove(obj, 'c.d[1]');\n  obj.print;\n  -- remove null element\n  pljson_ext.remove(obj, 'c.d[1]');\n  obj.print;\n\n  -- you can ignore check for duplicate keys\n  obj := pljson();\n  -- enables fast construction without checks for duplicate keys\n  obj.check_duplicate(false);\n  for i in 1 .. 10 loop\n    obj.put('a'||i, i);\n  end loop;\n  obj.put('a'||5, 'tada');\n  obj.print;\n  obj.check_duplicate(true);\n  -- fix possible duplicates but does not preserve order\n  obj.remove_duplicates();\n  obj.print;\n\n  -- create json objects and lists from sql statements\n  list := pljson_dyn.executeList('select * from tab');\n  list.print;\n  obj := pljson_dyn.executeObject('select * from tab');\n  obj.print;\nend;\n/\n```\n\n### View json data as table (also works for json strings stored in table)\n```\nselect * from table(pljson_table.json_table(\n  '[\n    { \"id\": 0, \"displayname\": \"Back\",  \"qty\": 5, \"extras\": [ { \"xid\": 1, \"xtra\": \"extra_1\" }, { \"xid\": 21, \"xtra\": \"extra_21\" } ] },\n    { \"id\": 2, \"displayname\": \"Front\", \"qty\": 2, \"extras\": [ { \"xid\": 9, \"xtra\": \"extra_9\" }, { \"xid\": 90, \"xtra\": \"extra_90\" } ] },\n    { \"id\": 3, \"displayname\": \"Middle\", \"qty\": 9, \"extras\": [ { \"xid\": 5, \"xtra\": \"extra_5\" }, { \"xid\": 20, \"xtra\": \"extra_20\" } ] }\n  ]',\n  pljson_varray('[*].id', '[*].displayname', '[*].qty', '[*].extras[*].xid', '[*].extras[*].xtra'),\n  pljson_varray('id', 'displayname', 'qty', 'xid', 'xtra'),\n  table_mode =\u003e 'nested'\n));\n```\nreturns\n\n|ID | DISPLAYNAME|QTY|XID|XTRA|\n|:---|:---|:---|:---|:---|\n| 0\t| Back\t| 5\t| 1\t| extra_1 |\n| 0\t| Back\t| 5\t| 21|\textra_21|\n| 2\t| Front\t| 2\t| 9 |\textra_9 |\n| 2\t| Front\t| 2\t| 90|\textra_90|\n| 3\t| Middle| 9\t| 5 |\textra_5 |\n| 3 |\tMiddle| 9\t| 20|\textra_20|\n\n##### and many other (automatic support for Double numbers or Oracle numbers, base64 encode/decode, XML to json, etc.)\n\n### Notes about PL/JSON path operations\n\n- never raise an exception (null is returned instead)\n- arrays are 1-indexed\n- use dots to navigate through the json nested objects\n- the empty string as path returns the entire json object\n- 7 get types are supported: string, number, bool, null, json, json_list and date\n- spaces inside [ ] are not important, but are important otherwise\n- keys made with non-standard javascript characters must be enclosed in double quotes\n\n### Updated definition of json path expression syntax accepted by PL/JSON\n    \n- a path may optionally begin with $ indicating the JSON object to be matched (root)\n  then it's followed by 0 or more path steps\n  each step can be an object step or an array step, depending on whether the context item represents a JSON object or a JSON array\n\n- an object step is a period (.), sometimes read as \"dot\", followed by an object field name (object property name)\na field name must start with an uppercase or lowercase letter A to Z and contain only such letters or decimal digits (0-9),\nor else it must be enclosed in double quotation marks (\")\nOR\na left bracket ([) followed by a a field name enclosed in single (') or double (\") quotes, followed by a right bracket (])\n\n- an array step is a left bracket ([) followed by a single numeric index, followed by a right bracket (])\narray indexing is one-based (1, 2, 3,...)\n\n  examples:\n    $.store.book[0].title, $['store']['book'][0]['title']\n\nin latest update (since 3.6.0)\n- an object step, beginning with dot (.), now accepts name within double quotes (\")\n- no longer accepts name beginning with, ending with and including spaces eg. 'd.  a name  .data'\n\n- in past, after a dot (.) the field name could start with space or number\n  and include or end with any number of spaces\n  now this is not allowed, unquoted field names must begin with an alpha character or _\n  and contain only alphanumeric characters\n\n- path expressions are now compatible with Oracle Basic SQL/JSON Path Expression Syntax\n  but excluding the optional filter expression and the optional function step at end\n\n## Install\n\n1.  Download the latest release -- https://github.com/pljson/pljson/releases\n2.  Extract the zip file\n3.  Use `sql*plus`, or something capable of running `sql*plus` scripts, to\n    run the `install.sql` script.\n4.  To test the implementation, run the `/testsuite/testall.sql` script\n \nWarning:\n\nThis installation currently works in the installation schema only (ie. you can't use it from other schema).\n\nIf you used version 2 in past and want to use the new version 3 in the same schema then\nyou must first uninstall version 2 (use uninstall.sql of version 2) and then install version 3.\n\n**NOTICE:**\n\nAll pljson types and packages start with 'PLJSON'.\nIn earlier releases they started with 'JSON', but this conflicted with new\nnative json support in Oracle 12c so they were renamed to start with PLJSON.\nFor backwards compatibility in version 2 there are created corresponding synonyms\nstarting with 'JSON'. In version 3 no such synonyms are created.\n\nMost of the examples use the old naming starting with 'JSON'.\nWhen you try the examples, and in your code, use `PLJSON_...` instead of `JSON_...`.\nAlso, the example code was made with version 2 api and has not been updated to version 3 api yet\nbut the differences are minor (see the initial description) and most code should work without change.\n\n## Documentation\n\nSee the version 2 documentation and study the main type specifications first.\nLater you can study the package specifications\nand I will also keep updating this README for more information.\n\n## Project folders and files\n\n+ **install.sql** install the pljson packages and types in your schema\n+ **uininstall.sql** completely uninstall packages and types\n+ **src/**  source code in PL/SQL, it is accessed by the install and uninstall scripts\n+ **examples/** useful examples to learn how to use pljson\n+ **testsuite/** a set of testsuites to verify installation, just run **testall.sql**\n+ **testsuite-utplsql/** the same set of testsuites but utilizing the utplsql framework (which you must install separately), just run **utplsql_testall.sql**\n\n## Support\nTo report bugs, suggest improvements, or ask questions, please create a new issue.\n\n## Contributing\nPlease follow the [contributing guidelines](CONTRIBUTING.md) to submit fixes or new features.\n\n## License\n[MIT License](LICENSE)\n","funding_links":[],"categories":["Libraries"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpljson%2Fpljson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpljson%2Fpljson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpljson%2Fpljson/lists"}