# How to evaluate string as script?

**URL:** <https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087>\
**Category:** Ignition\
**Created:** [July 28, 2023, 7:58pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087 "2023-07-28T19:58:14Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zach\_The](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zach_the/32/49673_2.png) [@Zach\_The](https://forum.inductiveautomation.com/u/Zach_The)\
**Post date:** [July 28, 2023, 7:58pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/1 "2023-07-28T19:58:14Z")

</div>

In a component script, is there a way to evaluate a string as a line of the script?

For example...

system.db.runPrepUpdate(query, [10])

could be replaced with...

i = 10  
evaluate(stringFormat("system.db.runPrepUpdate(query, [%d])", i)

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [July 28, 2023, 8:02pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/2 "2023-07-28T20:02:52Z")

</div>

What problem are you trying to solve? You can just use,

```auto
i = 10
system.db.runPrepUpdate(query, [i])

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 28, 2023, 8:03pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/3 "2023-07-28T20:03:52Z")

</div>

What problem are you trying to solve? Let us help you find a safe way to do what you need.

---

<div class="post-metadata">

**Author:** ![Zach\_The](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zach_the/32/49673_2.png) [@Zach\_The](https://forum.inductiveautomation.com/u/Zach_The)\
**Post date:** [July 28, 2023, 8:06pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/4 "2023-07-28T20:06:30Z")

</div>

I am trying to make 'save recipe' 'upload recipe' 'download recipe' buttons that will dynamically pull all the tags from a folder and add it to the query

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 28, 2023, 8:10pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/5 "2023-07-28T20:10:12Z")

</div>

That doesn't explain why you need to evaluate a string as jython/python. You might possibly need to construct a SQL query dynamically, but careful DB architecture should avoid that, too. Please share some examples of the data you need in these recipes.

(For a fully generic way to associate tags and values, consider examining the [database architecture for Ignition's own historian](https://docs.inductiveautomation.com/display/DOC81/Ignition+Database+Table+Reference). No dynamic jython nor dynamic SQL required, aside from partitioned table names.)

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [July 28, 2023, 8:20pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/6 "2023-07-28T20:20:34Z")

</div>

I don't think you've thought this through. For example, upload and download can't both be reading tags and writing to the database. One should transfer from tags to DB and the other the opposite - depending on which way you think is "up".

When you need to write to the database you read your tags into a list and provide that list of values as arguements to your query.

```auto
# Pseudo code ...
tagPaths = ["path/tag1", "path/tag2", "path/tag3"]
qualifiedValues = system.tag.readBlocking(tagPaths)
args = []
for tag in qualifiedValues:
    args.append(tag.value)
query = """INSERT INTO myTable (recipeParam1, recipeParam2, recipeParam3) 
           VALUES (?, ?, ?)"""
system.db.runPrepUpdate(query, args)

```

Further reading:

[https://docs.inductiveautomation.com/display/DOC81/system.tag.readBlocking](https://docs.inductiveautomation.com/display/DOC81/system.tag.readBlocking)

[https://docs.inductiveautomation.com/display/DOC81/system.db.runPrepUpdate?src=sidebar](https://docs.inductiveautomation.com/display/DOC81/system.db.runPrepUpdate?src=sidebar)

---

<div class="post-metadata">

**Author:** ![Zach\_The](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zach_the/32/49673_2.png) [@Zach\_The](https://forum.inductiveautomation.com/u/Zach_The)\
**Post date:** [July 28, 2023, 8:25pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/7 "2023-07-28T20:25:30Z")

</div>

There are separate buttons for selecting, saving, deleting, uploading, and downloading. First 3 push and pull from the sql database and the last 2 just assign memory tags to opc tags

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 28, 2023, 8:57pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/8 "2023-07-28T20:57:59Z")

</div>

> [@Zach\_The](#):
>
> the last 2 just assign memory tags to opc tags

Oooo! Sounds like an anti-pattern. Specifically, that you can't have two or more independent clients, each reviewing/editing/saving recipes, while another (perhaps with different privileges) transfers to/from the PLC.

Basically, don't use memory tags for user interfaces. User interfaces should use session custom properties (in Perspective) or Client Tags (in Vision) to perform the intermediate handling of recipe values.

(This anti-pattern is common when people with stand-alone HMI experience use a high-quality SCADA system for the first time.)

---

<div class="post-metadata">

**Author:** ![Zach\_The](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zach_the/32/49673_2.png) [@Zach\_The](https://forum.inductiveautomation.com/u/Zach_The)\
**Post date:** [July 31, 2023, 12:33pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/9 "2023-07-31T12:33:18Z")

</div>

Why can't/shouldn't mem tags be used for recipe handling? Is it because they can be accessed by other clients in the gateway?

Where should mem tags be used? Just for communicating between clients?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 31, 2023, 1:17pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/10 "2023-07-31T13:17:38Z")

</div>

> [@Zach\_The](#):
>
> they can be accessed by other clients in the gateway?

Precisely. If two clients, or client + designer, are both looking at that UI, they will interfere with each other.

> [@Zach\_The](#):
>
> Where should mem tags be used?

Memory tags hold **process** state, not UI state, or hold UI information that is **required** to be synchronized across clients.

---

<div class="post-metadata">

**Author:** ![Zach\_The](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zach_the/32/49673_2.png) [@Zach\_The](https://forum.inductiveautomation.com/u/Zach_The)\
**Post date:** [July 31, 2023, 1:31pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/11 "2023-07-31T13:31:48Z")

</div>

Awesome thank you! Off the top of your head are there any other considerations to make going from stand alone HMIs to Ignition?

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [July 31, 2023, 1:36pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/12 "2023-07-31T13:36:30Z")

</div>

> [@Zach\_The](#):
>
> Off the top of your head are there any other considerations

Not everything needs to be, nor should be a tag. This is the biggest thing for me, particularly if you come from a long history of AB experience. Some things that you were forced to make a tag in other platforms just don't need to be that.

---

<div class="post-metadata">

**Author:** ![Zach\_The](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zach_the/32/49673_2.png) [@Zach\_The](https://forum.inductiveautomation.com/u/Zach_The)\
**Post date:** [July 31, 2023, 2:01pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/13 "2023-07-31T14:01:58Z")

</div>

I've been trying to keep everything in scripts which is really nice after Wonderware

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [July 31, 2023, 2:12pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/14 "2023-07-31T14:12:02Z")

</div>

> [@Zach\_The](#):
>
> I've been trying to keep everything in scripts

So, the first thing I would tell you is this: If you can do it as an expression, you absolutely should.

Use indirect binding and custom properties in combination with expressions. The expression language is ridiculously powerful, (especially if you can utilize @pturmel free Simulation Aids module). There are things that it can't do, like dynamic recursive searches, but for the most part I have found nearly everything I need to handle can be handled there.

Scripting is an extremely powerful tool, and it can unlock many doors, but some of those doors are locked for good reason.

I would recommend exhausting methods for accomplishing tasks with property bindings and expressions before finally moving on to a script. Otherwise you'll find your self with a nest of performance issues without really knowing why they're performing poorly (and that's the best outcome).

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 31, 2023, 2:15pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/15 "2023-07-31T14:15:58Z")

</div>

> [@Zach\_The](#):
>
> I've been trying to keep everything in scripts

Actually, don't. Or rather, use expression bindings first, where you can. They are much more efficient than scripted equivalents. Anywhere you are using a property change event of some kind, take a hard look at whether it should be a binding at the receiving end.

Scripts that handle other events likely cannot be converted to expression bindings, so don't look hard there. However, avoid writing event scripts or transforms that are more than one or two lines. Those should call a project library function instead. That is where scripts are best maintained and most performant (and can have cached/static values that persist from one call to another).

---

<div class="post-metadata">

**Author:** ![Zach\_The](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zach_the/32/49673_2.png) [@Zach\_The](https://forum.inductiveautomation.com/u/Zach_The)\
**Post date:** [July 31, 2023, 2:56pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/16 "2023-07-31T14:56:41Z")

</div>

Much appreciated!

---

<div class="post-metadata">

**Author:** ![Zach\_The](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zach_the/32/49673_2.png) [@Zach\_The](https://forum.inductiveautomation.com/u/Zach_The)\
**Post date:** [July 31, 2023, 3:07pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/17 "2023-07-31T15:07:29Z")

</div>

When making new projects for new machines, should you also be making new databases and connections and stuff that are associated with that project?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 31, 2023, 3:34pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/18 "2023-07-31T15:34:03Z")

</div>

Varies. Generally not multiple databases, as that complicates site-wide dashboards.

---

<div class="post-metadata">

**Author:** ![Zach\_The](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zach_the/32/49673_2.png) [@Zach\_The](https://forum.inductiveautomation.com/u/Zach_The)\
**Post date:** [August 1, 2023, 12:36pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/19 "2023-08-01T12:36:11Z")

</div>

Just for clarification, do the different schemas in MySQL count as different databases or are the different servers the databases?

Basically does this count as 3 databases or just 3 groups in the same database?  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/8/e8a0d2f2360c2d20d4f5a92a168a97243250eee8.png)

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 1, 2023, 12:44pm UTC](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087/20 "2023-08-01T12:44:00Z")

</div>

The point where it counts is when setting up your connection(s) in Ignition. If you can access all of the schemas from one Ignition connection, it is effectively one database. Probably still not recommended, though, as it will likely confuse your designer's query utilities.

[Next page](https://forum.inductiveautomation.com/t/how-to-evaluate-string-as-script/77087.md?page=2)
