Correct syntax for DbContext.Database.ExecuteSqlRaw() - entity-framework-core

I've been frustrating myself for too long trying to get the syntax for an Insert correct and am hoping someone can point out my error. I'm using EF Core 5.0.1.
I am trying to insert on the following table using raw SQL:
CREATE TABLE [dbo].[MyTable](
[MyTableId] [smallint] IDENTITY(1,1) NOT NULL,
[Description] [nvarchar](50) NOT NULL,
[UpdateDt] [datetime] NOT NULL,
[UpdateBy] [nvarchar](30) NOT NULL,
[CreateDt] [datetime] NOT NULL,
[CreateBy] [nvarchar](30) NOT NULL,
CONSTRAINT [PK_C_MyTable] PRIMARY KEY CLUSTERED
(
[MyTableId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
I've tried this:
dbContext.Database.ExecuteSqlRaw($"INSERT INTO MyTable(Description, UpdateDt, UpdateBy, CreateDt, CreateBy) VALUES(#Description, #UpdateDt, #UpdateBy, #CreateDt, #CreateBy)", new[] { "status description", "2021-01-17 10:47:45.760", "updater", "2021-01-17 10:47:45.760", "creator" });
I also tried this:
db.Database.ExecuteSqlRaw($"INSERT INTO MyTable (Description, UpdateDt, UpdateBy, CreateDt, CreateBy) VALUES(#Description, #UpdateDt, #UpdateBy, #CreateDt, #CreateBy)", "status description", "2021-01-17 10:47:45.760", "updater", "2021-01-17 10:47:45.760", "creator");
Running either of these gives me the following exception:
System.TypeInitializationException : The type initializer for 'MyClass' threw an exception.
---- Microsoft.Data.SqlClient.SqlException : Must declare the scalar variable "#Description".
I have a hunch I'm overlooking something that's going to make me want to slap my forehead later, but am hoping someone can see what I'm doing wrong.

dbContext.Database.ExecuteSqlRaw(
$"INSERT INTO MyTable(Description, UpdateDt, UpdateBy, CreateDt, CreateBy) VALUES({0}, {1}, {2}, {3}, {4})",
new[]
{
"status description", "2021-01-17 10:47:45.760", "updater", "2021-01-17 10:47:45.760", "creator"
});
This should work. The problem with your solution is that #description, #updatedDt doesn't work as a placeholder. Please follow this documentation here .

Related

Laravel 8 Eloquent migration generated error " 1068 Multiple primary key defined"

I have the following migration file:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateHeadersTable extends Migration
{
public function up()
{
Schema::create('headers', function (Blueprint $table) {
$table->increments('entry')->unsigned();
$table->string('id',16);
$table->string('address',256);
$table->string('desciption',512)->nullable()->default('NULL');
$table->tinyInteger('currency',)->default('0');
$table->decimal('sum',13,4);
$table->datetime('entered');
$table->tinyInteger('aborted',)->default('0');
$table->primary('entry');
});
}
public function down()
{
Schema::dropIfExists('headers');
}
}
This file was automatically generated by an online tool from a SQL file. However, when I ran "php artisan migrate," I got the following error:
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'headers'
already exists (SQL: create table `headers` (`entry` int unsigned not null
auto_increment primary key, `id` varchar(16) not null, `address`
varchar(256) not null, `desciption` varchar(512) null default 'NULL',
`currency` tinyint not null default '0', `sum` decimal(13, 4) not null,
`entered` datetime not null, `aborted` tinyint not null default '0')
default character set utf8mb4 collate 'utf8mb4_unicode_ci')
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:712
708▕ // If an exception occurs when attempting to run a query, we'll format the error
709▕ // message to include the bindings with SQL, which will make this exception a
710▕ // lot more helpful to the developer instead of just the database's errors.
711▕ catch (Exception $e) {
➜ 712▕ throw new QueryException(
713▕ $query, $this->prepareBindings($bindings), $e
714▕ );
715▕ }
716▕ }
+9 vendor frames
10 database/migrations/2023_01_31_1675138133_create_headers_table.php:23
Illuminate\Support\Facades\Facade::__callStatic()
+22 vendor frames
33 artisan:37
Illuminate\Foundation\Console\Kernel::handle()
I am not familiar with Laravel migration files. How can I fix this? Many thanks!
Do not drop the table manually. use php artisan migrate:rollback
and then re-try php artisan migrate
Error you got states that Table 'headers' already exists in database if you have deleted table from database just check their may be entry in migrations table in database just delete it and run migration again

Get the groups of a customeruser in otrs

I am extending OTRS with an app and need to get the groups a customeruser is in. I want to do this by communicating with the SessionGet-Endpoint (https://doc.otrs.com/doc/api/otrs/6.0/Perl/Kernel/GenericInterface/Operation/Session/SessionGet.pm.html)
The Endpoint for SessionGet returns a lot of information about the user but not the groups he is in. I am not talking about agents who can login to the backend of otrs but customerusers.
I am using OTRS 6 because it was the only one available in docker. I created the REST-endpoints in the backend and everything works well. There is a new functionality why I need to get the information about the groups.
Had a look at the otrs system-config but could not figure out if it is possible to include this information in the response.
Although I am a programmer, I did not want to write perl because of ... reasons.
I had a look at the file which handles the incoming request at /opt/otrs/Kernel/GenericInterface/Operation/Session/SessionGet.pm and traced the calls to the actual file where the information is collected from the database in /opt/otrs/Kernel/System/AuthSession/DB.pm. In line 169 the SQL-statement is written so it came to my mind that I just can extend this to also get the information of the groups, because, as I said, I did not want to write perl...
A typical response from this endpoint looks like this:
{
"SessionData": [
{
"Value": "2",
"Key": "ChangeBy"
},
{
"Value": "2019-06-26 13:43:18",
"Key": "ChangeTime"
},
{
"Value": "2",
"Key": "CreateBy"
},
{
"Value": "2019-06-26 13:43:18",
"Key": "CreateTime"
},
{
"Value": "XXX",
"Key": "CustomerCompanyCity"
},
{
"Value": "",
"Key": "CustomerCompanyComment"
}
...
}
A good thing would be to just insert another Value-Key-pair with the IDs of the groups. The SQL-statement queries only one table $Self->{SessionTable} mostly called otrs.sessions.
I used the following resources to create a SQL-statement which extends the existing SQL-statement with the needed information. You can find it here:
$DBObject->Prepare(
SQL => "
(
SELECT id, data_key, data_value, serialized FROM $Self->{SessionTable} WHERE session_id = ? ORDER BY id ASC
)
UNION ALL
(
SELECT
(
SELECT MAX(id) FROM $Self->{SessionTable} WHERE session_id = ?
) +1
AS id,
'UserGroupsID' AS data_key,
(
SELECT GROUP_CONCAT(DISTINCT group_id SEPARATOR ', ')
FROM otrs.group_customer_user
WHERE user_id =
(
SELECT data_value
FROM $Self->{SessionTable}
WHERE session_id = ?
AND data_key = 'UserID'
ORDER BY id ASC
)
)
AS data_value,
0 AS serialized
)",
Bind => [ \$Param{SessionID}, \$Param{SessionID}, \$Param{SessionID} ],
);
Whoever needs to get the groups of a customeruser can replace the existing code with the one provided. At least in my case it works very well. Now, I get the expected key-value-pair:
{
"Value": "10, 11, 6, 7, 8, 9",
"Key": "UserGroupsID"
},
I used the following resources:
Adding the results of multiple SQL selects?
Can I concatenate multiple MySQL rows into one field?
Add row to query result using select
Happy coding,
Nico

Stuck at Getting Survey Details from SurveyMonkey REST Connection in QlikSense

I'm trying to connect to the Survey Monkey API via a hard coded connection set in a variable but the connection is giving me such error:
QVX_UNEXPECTED_END_OF_DATA: HTTP protocol error 400 (Bad Request):
{
"error":
{
"docs": "https://developer.surveymonkey.com/api/v3/#error-codes",
"message": "Invalid URL parameters.", "id": "1003", "name": "Bad Request",
"http_status_code": 400
}
}
Although, if i try the same but while getting surveys bulk, it works
vID is equal to a survey id
let vURL2 = 'https://api.surveymonkey.com/v3/surveys/$(vID)/details';
RestConnectorMasterTable_SurveryFullDetails:
SQL SELECT
"response_count",
"page_count",
"date_created",
"folder_id",
"nickname",
"id" AS "id_u3",
"question_count" AS "question_count_u0",
"category",
"preview",
"is_owner",
"language",
"footer",
"date_modified",
"analyze_url",
"summary_url",
"href" AS "href_u1",
"title" AS "title_u0",
"collect_url",
"edit_url",
"__KEY_root",
(SELECT
"done_button",
"prev_button",
"exit_button",
"next_button",
"__FK_buttons_text"
FROM "buttons_text" FK "__FK_buttons_text"),
(SELECT
"__FK_custom_variables"
FROM "custom_variables" FK "__FK_custom_variables"),
(SELECT
"href" AS "href_u0",
"description" AS "description_u0",
"title",
"position" AS "position_u2",
"id" AS "id_u2",
"question_count",
"__KEY_pages",
"__FK_pages",
(SELECT
"sorting",
"family",
"subtype",
"visible" AS "visible_u1",
"href",
"position" AS "position_u1",
"validation",
"id" AS "id_u1",
"forced_ranking",
"required",
"__KEY_questions",
"__FK_questions",
(SELECT
"text",
"amount",
"type",
"__FK_required"
FROM "required" FK "__FK_required"),
(SELECT
"__KEY_answers",
"__FK_answers",
(SELECT
"visible",
"text" AS "text_u0",
"position",
"id",
"__FK_rows"
FROM "rows" FK "__FK_rows"),
(SELECT
"description",
"weight",
"visible" AS "visible_u0",
"id" AS "id_u0",
"is_na",
"text" AS "text_u1",
"position" AS "position_u0",
"__FK_choices"
FROM "choices" FK "__FK_choices")
FROM "answers" PK "__KEY_answers" FK "__FK_answers"),
(SELECT
"heading",
"__FK_headings"
FROM "headings" FK "__FK_headings")
FROM "questions" PK "__KEY_questions" FK "__FK_questions")
FROM "pages" PK "__KEY_pages" FK "__FK_pages")
FROM JSON (wrap on) "root" PK "__KEY_root"
WITH CONNECTION(Url "$(vURL2)");
Have you checked out this fairly exhaustive SurveyMonkey how to guide on the Qlik Community? Might we worth checking you've followed all those steps, including giving the user permission to access the API.
It is not enough to hardcode URL, you also need to specify authorization header
WITH CONNECTION (
Url "$(vURL2)",
HTTPHEADER "Authorization" "bearer YOUR_TOKEN"
);

EF7 rc1 Upgrade from Beta 6: Invalid column name

After upgrading from Beta 6 to RC1 - Final I get the following errors:
SqlException: Invalid column name 'Discriminator'.
Invalid column name 'Enabled'.
Invalid column name 'Slug'.
Invalid column name 'Discriminator'.
Invalid column name 'ThemeId'.
Invalid column name 'Content'.
Invalid column name 'DisplayInNavigation'.
Invalid column name 'Dynamic'.
Invalid column name 'Enabled'.
Invalid column name 'Layout'.
Invalid column name 'LinkText'.
Invalid column name 'Order'.
Invalid column name 'Slug'.
Invalid column name 'Title'.
This is my table structure:
CREATE TABLE [dbo].[PageContent](
[Id] [int] NOT NULL,
[Content] [nvarchar](max) NULL,
[Created] [datetime2](7) NULL,
[DeletedDate] [datetime2](7) NULL,
[DisplayInNavigation] [bit] NOT NULL,
[Dynamic] [bit] NOT NULL,
[Enabled] [bit] NOT NULL,
[Layout] [nvarchar](max) NULL,
[LinkText] [nvarchar](max) NULL,
[Modified] [datetime2](7) NULL,
[Order] [int] NOT NULL,
[Slug] [nvarchar](max) NULL,
[Title] [nvarchar](max) NULL,
[ThemeId] [int] NOT NULL,
CONSTRAINT [PK_PageContent] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
and my Migrations:
migration.CreateTable(
name: "PageContent",
columns: table => new
{
Id = table.Column<int>(nullable: false),
Content = table.Column<string>(nullable: true),
Created = table.Column<DateTime>( nullable: true),
DeletedDate = table.Column<DateTime>( nullable: true),
DisplayInNavigation = table.Column<bool>( nullable: false),
Dynamic = table.Column<bool>( nullable: false),
Enabled = table.Column<bool>( nullable: false),
Layout = table.Column<string>(nullable: true),
LinkText = table.Column<string>(nullable: true),
Modified = table.Column<DateTime>( nullable: true),
Order = table.Column<int>(nullable: false),
Slug = table.Column<string>(nullable: true),
Title = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PageContent", x => x.Id);
});
migration.AddColumn<int>(
name: "ThemeId",
table: "PageContent",
nullable: false,
defaultValue: 0);

PostgreSQL and Glassfish EJB__TIMER__TBL table

I'm trying to use the timer service provided by Glassfish. Thus, I have to create a table named EJB__TIMER__TBL and configure jdbc resource in Glassfish.
I want to store this table on postgreSQL on a schema named glassfish. So my ddl is this one (I replace the BLOB type to BYTEA) :
CREATE SCHEMA glassfish;
CREATE TABLE glassfish.EJB__TIMER__TBL (
CREATIONTIMERAW BIGINT NOT NULL,
BLOB BYTEA,
TIMERID VARCHAR(255) NOT NULL,
CONTAINERID BIGINT NOT NULL,
OWNERID VARCHAR(255) NULL,
STATE INTEGER NOT NULL,
PKHASHCODE INTEGER NOT NULL,
INTERVALDURATION BIGINT NOT NULL,
INITIALEXPIRATIONRAW BIGINT NOT NULL,
LASTEXPIRATIONRAW BIGINT NOT NULL,
SCHEDULE VARCHAR(255) NULL,
APPLICATIONID BIGINT NOT NULL,
CONSTRAINT PK_EJB__TIMER__TBL PRIMARY KEY (TIMERID)
);
DROP ROLE IF EXISTS glassfish;
CREATE ROLE glassfish WITH NOINHERIT LOGIN PASSWORD '...';
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA glassfish FROM glassfish;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA glassfish FROM glassfish;
GRANT USAGE ON SCHEMA glassfish TO glassfish;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA glassfish TO glassfish;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA glassfish TO glassfish;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA glassfish TO glassfish;
ALTER USER glassfish SET search_path to 'glassfish';
I configured a jdbc pool and resource for Glassfish :
asadmin create-jdbc-connection-pool
--datasourceclassname org.postgresql.ds.PGConnectionPoolDataSource
--restype javax.sql.ConnectionPoolDataSource
--property User=glassfish:Password=...:PortNumber=5432:DatabaseName=...:ServerName=localhost jdbc/simPool/glassfish
asadmin create-jdbc-resource --connectionpoolid jdbc/simPool/glassfish jdbc/sim/glassfish
And I properly enter jdbc/sim/glassfish in the jdbc resource to use for timer service in Glassish GUI.
Each time I deploy my app, I receive Exception :
[#|2013-02-18T11:42:42.562+0100|WARNING|glassfish3.1.2|org.eclipse.persistence.session.file
:/E:/softs/serveurs/glassfish3_1122/glassfish/domains/domain1/applications/ejb-timer-service-app/WEB-INF/classes/___EJB__Timer__App|_ThreadID=58;_ThreadName=Thread-2;|Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERREUR: la relation « EJB__TIMER__TBL » n'existe pas
Position : 193
Error Code: 0
Call: SELECT "TIMERID", "APPLICATIONID", "BLOB", "CONTAINERID", "CREATIONTIMERAW", "INITIALEXPIRATIONRAW", "INTERVALDURATION", "LASTEXPIRATIONRAW", "OWNERID", "PKHASHCODE", "SCHEDULE", "STATE" FROM "EJB__TIMER__TBL" WHERE (("OWNERID" = ?) AND ("STATE" = ?))
bind => [2 parameters bound]
Query: ReadAllQuery(name="findTimersByOwnerAndState" referenceClass=TimerState sql="SELECT "TIMERID", "APPLICATIONID", "BLOB", "CONTAINERID", "CREATIONTIMERAW", "INITIALEXPIRATIONRAW", "INTERVALDURATION", "LASTEXPIRATIONRAW", "OWNERID", "PKHASHCODE", "SCHEDULE", "STATE" FROM "EJB__TIMER__TBL" WHERE (("OWNERID" = ?) AND ("STATE" = ?))")
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:644)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1717)
So my table EJB__TIMER__TBL doesn't seem to be accessible by Glassfish.
When I create another project, configure a persistence.xml file with the same credentials as my pooled connexion above and create a simple query SELECT COUNT(*) FROM EJB__TIMER__TBL, I receive 0 so my connexion is well established and the default schema accessed is glassfish as espected.
In ${glassfish_root}\glassfish\lib\install\databases there is some ddls but neither for postgresql...so where am I doing wrong ?
NB: when I test to configure service timer with MySQL jdbc resource, it's work...
Thanks for help
Ok I found the solution of my problem.
I didn't know that SQL can be case sensitive. Glassfish calls SELECT ... FROM "EJB__TIMER__TBL" with double quotes so I have to create a table named "EJB__TIMER__TBL" not "ejb__timer__tbl" or anything else.
The workaround is just to recreate my table with double quotes :
CREATE TABLE glassfish."EJB__TIMER__TBL" (
"CREATIONTIMERAW" BIGINT NOT NULL,
"BLOB" BYTEA,
"TIMERID" VARCHAR(255) NOT NULL,
"CONTAINERID" BIGINT NOT NULL,
"OWNERID" VARCHAR(255) NULL,
"STATE" INTEGER NOT NULL,
"PKHASHCODE" INTEGER NOT NULL,
"INTERVALDURATION" BIGINT NOT NULL,
"INITIALEXPIRATIONRAW" BIGINT NOT NULL,
"LASTEXPIRATIONRAW" BIGINT NOT NULL,
"SCHEDULE" VARCHAR(255) NULL,
"APPLICATIONID" BIGINT NOT NULL,
CONSTRAINT "PK_EJB__TIMER__TBL" PRIMARY KEY ("TIMERID")
);