Oracle's 'CHECK' CONSTRAINT in 'CREATE TYPE nnn AS OBJECT' -clause - oracle10g

It seems that it is not possible to define the CHECK -constraint in the CREATE TYPE -clause. This is doable in the CREATE TABLE -clause. Wondering if I'm doing something wrong here, since it feels that it would be convenient to use it in TYPE -definitions and further refer it in the CREATE TABLE -part.
CREATE TYPE address_type AS OBJECT (
StreetAddress varchar2(200),
City varchar2(50),
AddressType varchar2(20)
constraint ckAddressType check (AddressType in ('HO address', 'Billing address', 'Other address'))
);
This produces an error
"[Error] PLS-00103 (5: 3): PLS-00103: Encountered the symbol
"CONSTRAINT" when expecting one of the following: := ) , ei tyhjä
oletus external character"

Related

Postgresql - querying jsonb throws a syntax error

I have a table that has a column data of jsonb type.
create table event
(
id bigserial
primary key,
created_at timestamp with time zone default now() not null,
type text not null,
created_by text,
data jsonb,
event_time timestamp with time zone default now() not null
);
In that field I am saving a json object that looks like this:
{
"comment": "Changed by recipient",
"source": "Recipient page"
}
I would like to query values in that table by the value of the comment property of the data json object. Something like this in based by examples [here][1]:
select * from event
where type = 'pickup-data-changed'
and data -> 'comment' = 'Changed by recipient'
If I query like that I get an invalid token error:
[22P02] ERROR: invalid input syntax for type json Detail: Token "Changed" is invalid. Position: 104
What am I doing wrong here?
If I do it as a double arrow like suggested in the comments:
select * from event
where type = 'pickup-data-changed'
and data ->-> 'comment' = 'Changed by recipient'
I get an error:
[42883] ERROR: operator does not exist: jsonb ->-> unknown Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
How can I make this query work?
[1]: https://kb.objectrocket.com/postgresql/how-to-query-a-postgres-jsonb-column-1433
I get an invalid token error. What am I doing wrong here?
data -> 'comment' returns a value of type jsonb, so the right hand side of the comparison 'Changed by recipient' is parsed as JSON as well - and it's invalid JSON. To create a JSON string value to compare against, you'd need to write
… data -> 'comment' = '"Changed by recipient"'
If I do it as a double arrow like suggested in the comments, data ->-> 'comment'
The comments suggested
… data ->> 'comment' = 'Changed by recipient'
not ->->.
alternatives:
select * from event
where type = 'pickup-data-changed'
and data -> 'comment' = '"Changed by recipient"'::jsonb;
or
select * from event
where type = 'pickup-data-changed'
and data['comment'] = '"Changed by recipient"'::jsonb;

Drools - check if argument is null before calling query

Inside the drools rule file, I'm trying to match the request object against inserted facts using a query (backward chaining). How do I check for null for the request object attribute? If the attribute is not null, I want to pass it to the query. If the attribute is null, I want to keep it unbound so that it will match all results. Since there are many request attributes, I'm looking for a generic solution instead of different rules for each attribute.
To give an example, lets assume I have two attributes currency and country in the goal: Goal() object and I want to call the query isMatching(String country,String currency)
if goal.getCountry() and goal.getCurrency() is not null, I want to call isMatching with goal.getCountry()and goal.getCurrency().
isMatching(goal.getCountry(),goal.getCurrency())
if goal.getCountry() is null and goal.getCurrency() is not null, I want to call isMatching with unbound variable country and goal.getCurrency()
isMatching(country,goal.getCurrency())
if goal.getCountry() is not null and goal.getCurrency() is null, I want to call isMatching with goal.getCountry() and unbound variable currency
isMatching(goal.getCountry(),currency)
if both goal.getCountry() and goal.getCurrency() are null, I want to call isMatching with unbound variable country and currency
isMatching(country,currency)
Best practice is to have a separate rule for each combination.
rule "both country and currency"
when
Goal( $country: country != null, $currency: currency != null )
$isMatching: Boolean() from isMatching( $country, $currency )
then
//
end
Not sure what you're referring to as an "unbound" variable in your question for your other use cases.
If you insist on not following best practices and try to kludge all of this into a single rule, you could either do your null check on the right hand side, or possibly abuse conditional and named consequences to do this. Doing it in the rule consequences ("then") will cause you to lose all of the performance optimization done by the Drools engine, which is done on the left hand side only.
Alternatively you could just update the query to handle the null case.
query isMatching( String $country, String $currency) {
$country := String( this == null )
or
$currency := String( this == null )
or
( actual implementation )
}
rule "example"
when
Goal( $country: country, $currency: currency )
isMatching( $country, $currency )
then
// ...
end
Actual implementation may vary; I have no idea how you'd implement a currency <-> country check.

How do I tell my migration what column type to use?

I'm using Rails 5 and PostGres 9.5. I have created this migration
class CreateSearchCodeTable < ActiveRecord::Migration[5.0]
def change
create_table :search_codes do |t|
t.string :code
t.references :address, index: true, foreign_key: true, on_delete: :cascade
t.index ["code"], name: "index_search_codes_on_code", unique: true, using: :btree
end
end
end
The ID column of the address table is not an integer though. Maybe for that reason, I get the below error when I run the migration
== 20171011202623 CreateSearchCodeTable: migrating ============================
-- create_table(:search_codes)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::DatatypeMismatch: ERROR: foreign key constraint "fk_rails_6bd9792e3b" cannot be implemented
DETAIL: Key columns "address_id" and "id" are of incompatible types: integer and character varying.
: CREATE TABLE "search_codes" ("id" serial primary key, "code" character varying, "address_id" integer, CONSTRAINT "fk_rails_6bd9792e3b"
FOREIGN KEY ("address_id")
REFERENCES "addresses" ("id")
)
How do I instruct my migration to create my column with the same type as the referenced column?
t.references delegates job to add_reference and this one accepts :type parameter. Judging from this, you should be able to do
t.references :address, type: :string, index: true, foreign_key: true, on_delete: :cascade
^^^^^^^^^^^^^
Just tested this on a toy sqlite3-based project, it worked. Should "just work" on pg too.
How do I instruct my migration to create my column with the same type as the referenced column?
If you meant to tell it to infer the type of the other column and have type of this one match it, then this is likely not possible. But you can always specify type explicitly.

PostgreSQL to Java Data Types (Grails)

I have the following (Grails) domain object:
class Country {
Integer id
char country_abbr
String country_name
static mapping = {
version false
id name: 'id'
table 'country'
id generator:'identity', column:'id'
}
static constraints = {
}}
The 'country_abbr' field within the 'country table' has type: character(2). However, whenever I am setting the domain object's data type (for 'country_abbr') to String, initialization is failing with the following exception
org.hibernate.HibernateException: Wrong column type in mydb.country for column country_abbr. Found: bpchar, expected: varchar(255)
On the other hand, leaving this type as a Java char would only retrieve the first character. Any ideas how may I map to this type? Also, what is bpchar exactly?
Thanks
Just to make this question answered. The solution is to change the country_abbr mapping:
country_abbr columnDefinition: 'char'
Reference here.

How can I use an hstore column type with Npgsql?

I have a table with the following schema:
CREATE TABLE account
(
id serial primary key,
login varchar(40) not null,
password varchar(40) not null,
data hstore
);
I'd like to use an NpgsqlCommand object with parameters to retrieve and store the account data from my application. Which DbType do I have to use for the NpgsqlParameter? The enum NpgsqlDbType does not have a value for hstore. Can I use a Dictionary or HashTable as value of the NpgsqlParameter object?
When I use a JSON column I can create a parameter of type NpgsqlDbType.Text, use a library like JSON.Net to serialize an object to a JSON string and send an SQL statement like that:
INSERT INTO account (login, password, data) VALUES (:login, :password, :data::json)
Unfortunately this does not work with an hstore column. I get a syntax error when I try to do this:
INSERT INTO account (login, password, data) VALUES (:login, :password, :data::hstore)
The string I pass to the data parameter looks like this:
'key1 => "value1", key2 => "value2"'
Thank you, Francisco! I saw in the log that the single quotes (') at the beginning and the end of the string are escaped when they are passed to PostgreSQL. When I pass
key1 => "value1", key2 => "value2"
instead, I can insert the data into the hstore column.